网站平面设计完成后 与客户怎样沟通,做网站一般多钱,闵行区核酸检测点,wordpress 做购物网站关于闭包#xff0c;初学者会被绕的晕头转向#xff0c;在学习的路上也付出了很多精力来理解。 让我们一起来揭开闭包神秘的面纱。 闭包晦涩的定义 看过很多关于闭包的定义#xff0c;很多讲的云里雾里#xff0c;晦涩难懂。让不少人以为闭包是多么玄乎的东西。在我看过的所…关于闭包初学者会被绕的晕头转向在学习的路上也付出了很多精力来理解。 让我们一起来揭开闭包神秘的面纱。 闭包晦涩的定义 看过很多关于闭包的定义很多讲的云里雾里晦涩难懂。让不少人以为闭包是多么玄乎的东西。在我看过的所有书籍中我更喜欢《你不知道的javascript上卷》的定义 当函数可以记住并访问所在的词法作用域时就产生了闭包或者说函数在创建时的词法作域之外执行。 通俗的来说不严谨 就是函数套函数子函数可以有权访问父函数的变量、父函数的父函数的变量、一直到全局变量。子函数如果不被销毁,整条作用域链上的变量仍然保存在内存中。 关于词法作用域这里不做过多的解释详情参考http://www.cnblogs.com/ylweb/p/7531259.html. 下面用一些代码来解释这个定义 function foo() {var a 2;function bar() {console.log( a ); // 2}bar();
}foo(); 严格来说这段代码并没有形成闭包因为bar是在创建时所在的词法作用域执行。bar() 对a 的引用的方法是词法作用域的查找规则而这些规则只是闭包的一部分。从学术的角度说在上面的代码片段中函数bar() 具有一个涵盖foo() 作用域的闭包 事实上涵盖了它能访问的所有作用域比如全局作用域。也可以认为bar() 被封闭在 了foo() 的作用域中。为什么呢原因简单明了因为bar() 嵌套在foo() 内部。 下面我们来看一段代码清晰地展示了闭包 function foo() {var a 2;function bar() {console.log( a );}return bar;
}var baz foo();
baz(); // 2 —— 朋友这就是闭包的效果。 函数bar() 的词法作用域能够访问foo() 的内部作用域。然后我们将bar() 函数本身当作一个值类型进行传递。在这个例子中我们将bar 所引用的函数对象本身当作返回值。 在foo() 执行后其返回值也就是内部的bar() 函数赋值给变量baz 并调用baz()实际上只是通过不同的标识符引用调用了内部的函数bar()。 bar() 显然可以被正常执行。但是在这个例子中它在自己定义的词法作用域以外的地方执行。 在foo() 执行后通常会期待foo() 的整个内部作用域都被销毁因为我们知道引擎有垃圾回收器用来释放不再使用的内存空间。由于看上去foo() 的内容不会再被使用所以很自然地会考虑对其进行回收。 而闭包的“神奇”之处正是可以阻止这件事情的发生。事实上内部作用域依然存在因此没有被回收。谁在使用这个内部作用域原来是bar() 本身在使用。 拜bar() 所声明的位置所赐它拥有涵盖foo() 内部作用域的闭包使得该作用域能够一直存活以供bar() 在之后任何时间进行引用。 bar() 依然持有对该作用域的引用而这个引用就叫作闭包。 循环与闭包 以下是一个最常见的for循环例子 for (var i1; i5; i) {setTimeout( function timer() {console.log( i );}, i*1000 );
} 正常情况下我们对这段代码行为的预期是分别输出数字1~5但实际上这段代码在运行时输出五次6。 Why 首先解释6 是从哪里来的。这个循环的终止条件是i 不再5。条件首次成立时i 的值是6。因此输出显示的是循环结束时i 的最终值。 仔细想一下这好像又是显而易见的延迟函数的回调会在循环结束时才执行。事实上当定时器运行时即使每个迭代中执行的是setTimeout(.., 0)所有的回调函数依然是在循环结束后才会被执行因此会每次输出一个6 出来。 问题实质 我们试图假设循环中的每个迭代在运行时都会给自己“捕获”一个i 的副本。但是根据作用域的工作原理实际情况是尽管循环中的五个函数是在各个迭代中分别定义的但是它们都被封闭在一个共享的全局作用域中因此实际上只有一个i。 改进方案 for (var i1; i5; i) {(function(j) {setTimeout( function timer() {console.log( j );}, j*1000 );})( i );
} ES6改进 for (let i1; i5; i) {setTimeout( function timer() {console.log( i );}, i*1000 );
} 转载于:https://www.cnblogs.com/ylweb/p/7804309.html