Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/441.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
理解JavaScript中的闭包_Javascript_Closures - Fatal编程技术网

理解JavaScript中的闭包

理解JavaScript中的闭包,javascript,closures,Javascript,Closures,想想这个 fs=[]; for(var i = 0; i < 3; i++){ fs.push(function(){ return i; }); } console.log(fs[0](),fs[1](),fs[2]()) fs=[]; 对于(变量i=0;i

想想这个

fs=[];
for(var i = 0; i < 3; i++){
  fs.push(function(){
    return i;
  });
}
console.log(fs[0](),fs[1](),fs[2]())
fs=[];
对于(变量i=0;i<3;i++){
fs.push(函数(){
返回i;
});
}
console.log(fs[0](),fs[1](),fs[2]())
我以为我会在函数的闭包中打印“01 2”,但是没有。。。它打印“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));
}
fs=[];
var makeFunc=函数(j){return function(){return j;}
对于(变量i=0;i<3;i++){
财政司司长推(makeFunc(i));
}

Javascript没有块作用域的概念,它只有函数作用域。因此,就寿命而言,
var i
的位置是没有意义的。它也可能是该方法的第一行

为了解决这个问题,您需要声明一个新的作用域,该作用域包含一个单独的
i

fs=[];
var makeFunc = function(j) { return function() { return j; } }
for(var i = 0; i < 3; i++){
  fs.push(makeFunc(i));
}
fs=[];
var makeFunc=函数(j){return function(){return j;}
对于(变量i=0;i<3;i++){
财政司司长推(makeFunc(i));
}

实际上,您正在将同一匿名函数的三个实例推送到“fs”数组中。然后,log语句调用该函数三次。在调用它时,循环已经完成,闭包中的'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]());
fs=[];
函数closureFunc(myVal){
返回函数(){
返回myVal;
}
}
对于(变量i=0;i<3;i++){
财政司司长推(closureFunc(i));
}
log(fs[0](),fs[1](),fs[2]());

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

实际上,您正在将同一匿名函数的三个实例推送到“fs”数组中。然后,log语句调用该函数三次。在调用它时,循环已经完成,闭包中的'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]());
fs=[];
函数closureFunc(myVal){
返回函数(){
返回myVal;
}
}
对于(变量i=0;i<3;i++){
财政司司长推(closureFunc(i));
}
log(fs[0](),fs[1](),fs[2]());

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

yepperino。。。现在有道理了。谢谢可能会有疑问,但与其说是声明一个新的作用域,不如说是创建一个新的
i
实例,这需要创建一个新的执行上下文。yepperino。。。现在有道理了。谢谢可能会有疑问,但与其说是声明一个新的作用域,不如说是创建一个新的
i
实例,这需要创建一个新的执行上下文。它返回“3”这一事实表明我处于闭包状态。每个被推到数组中的函数都有一个到相同i的闭包,因此它们都显示相同的值,这是最后一个分配给i的值(即3)。我可以。但let似乎没有被广泛采用。它返回“3”的事实表明我被关在一个封闭的地方。每个被推到数组中的函数都有一个到相同i的闭包,因此它们都显示相同的值,这是最后一个分配给i的值(即3)。我可以。但let似乎没有被广泛采用。