理解JavaScript中的闭包

时间:2014-02-12 23:33:29

标签: javascript closures

考虑一下

fs=[];
for(var i = 0; i < 3; i++){
  fs.push(function(){
    return i;
  });
}
console.log(fs[0](),fs[1](),fs[2]())

我以为我会关闭这个函数,以便打印“0 1 2”,但是没有...它会打印“3 3 3”。

为什么这不起作用?有没有办法让这项工作?

2 个答案:

答案 0 :(得分:3)

Javascript没有块范围的概念,它只有函数范围。因此,var i的位置在生命周期方面毫无意义。它也可能是该方法的第一行。

为了解决此问题,您需要声明一个包含单独i值的新范围

fs=[];
var makeFunc = function(j) { return function() { return j; } }
for(var i = 0; i < 3; i++){
  fs.push(makeFunc(i));
}

答案 1 :(得分:3)

您实际上是将同一个匿名函数的三个实例推送到'fs'数组中。然后你的日志语句调用该函数三次。在你调用它的时候,循环已经完成,闭包中的'i'值是3,所以这就是返回的内容。

我不确定你的“工作”是什么意思,但也许这就是你的意思:

fs = [];

function closureFunc(myVal) {
  return function () {
    return myVal;
  }
}

for (var i = 0; i < 3; i++) {
  fs.push(closureFunc(i));
}

console.log(fs[0](), fs[1](), fs[2]());

这会创建三个单独的闭包,其中您正在推送的函数具有声明函数“closureFunc”的作用域。在这些闭包中,myVal设置为传入的值。

相关问题