function foo() { var a=2; function bar() { console.log(a); } return bar; } var c = foo(); c();
这里会输出2 熟悉闭包的都知道 这边是为了自己再度认真总结下:
一般来说函数执行完以后其内容(作用域的内容)会被垃圾回收,但是闭包可以阻止其被回收,导致上面的c变量依旧能引用foo函数的作用域.
一个小例子:
for (var i = 1; i <= 5; i++) { setTimeout(function () { console.log(i); },i*1000); }
很多人会认为会分别输出1-5的数字,然而事实是会输出5个6.6是哪来的,最后一次循环之前累加到的6.
首先这里的延迟函数是在循环之后执行的,并且里面的闭包函数的作用域是独立的5个作用域,但是它们都共享外部作用域 所以会输出5个6;
想要依次输入1-5,可以这样改动:
for (var i = 1; i <= 5; i++) { (function (j) { setTimeout(function () { console.log(j); },j*1000); })(i) }
这里延迟函数所处的作用域是独立不共享的,所以这里也不会去引用i变量,js接受参数时候会创建副本,所以j是每次迭代计算出的i的副本。
也可以用let来声明i变量,解决上面的问题.