js闭包谈谈自己的理解吧?

function test1(){
  function test2(){
    var b = 2;
    console.log(a);
  }
  var a = 1;
  return test2;
}
var c = 3;
var test3 = test1();
test3();

之前就知道这里test2中会产生闭包,但是如果test2不访问test1里面的变量还会产生闭包吗?
就算用了test1里面变量如果他没被返回出去还会产生闭包吗,如果返回了没有被变量接受呢?又是什么情况?
在我心里感觉只要返回的test2被变量接受了,就会产生闭包那么test1的AO就不会被销毁,不管test3会不会执行。但是有点不确定。

看到立即执行函数 就又有点迷惑了

for(var i = 0 ; i<4;i++){
  (function(j){
      console.log(j)
  })(i)
}

看很多人说这样也会形成闭包,但是立即执行函数并没被返回,执行完也就销毁了,这和我刚才的结论有点矛盾。但是我感觉是不是看网上说的不对,for循环这里跟闭包没有关系,只是利用了立即执行函数的执行完就销毁的特性和函数的私有作用域来存储每次循环的i?
恳请各位大佬解惑!!!

阅读 1.6k
2 个回答

我也来自荐一个:javascript - 还搞不懂闭包算我输(JS 示例) - 边城客栈 - SegmentFault 思否


补充

关于 IIFE 的问题,我认为这里说是闭包有点勉强,因为函数产生立即在当前环境执行,并没有被带到环境之外去。

而之所以在循环里封装函数,目的是为了把循环变量带出去,看看下面的示例。

const fns1 = [];
const fns2 = [];
for (var i = 0; i < 4; i++) {
    fns1.push(() => console.log(i)); // 错误的示例,使用的最后的 i
    fns2.push((j => () => console.log(j))(i));  // 闭包带出当时的 i
}

console.log("fns1");
fns1.forEach(fn => fn());   // 4 4 4 4
console.log("fns2");
fns2.forEach(fn => fn());   // 0 1 2 3

示例中的错误/正确是说逻辑。但这两个示例从块级作用域来看都属于闭包,因为函数中把内部(块级)环境中的值带出去的。但从函数级作用域来看,说属于闭包有点勉强,毕竟还是在同一个作用域内运行,只是引用的值有所变化而已。之所在说有点勉强,而不是绝对,就在于函数里封装的那个值,说不清楚会不会在离开作用域的时候被回收(也就是评论中提到的可能会因为引擎实现不同而不同,理论上来说应该是会回收的,那就不能形成闭包了)。

推荐问题
宣传栏