gpt4 book ai didi

Javascript变量复制范围

转载 作者:搜寻专家 更新时间:2023-11-01 05:23:29 26 4
gpt4 key购买 nike

我有两段代码,我相信它们会产生相同的结果:

1.

for(var i=0;i<10;i+=1){
var j=i;
setTimeout(function(){
console.log(j);
},100);
}

2.

for(var i=0;i<10;i+=1){
(function(j){
setTimeout(function(){
console.log(j);
},100);
})(i);
}

但是,正如你们大多数人所料,第一个记录 9 十次,第二个从 0 到 9 正确记录。

第二个是使用闭包来保存 i 的值。我认为第一个也应该保留值(value),因为:

  1. var j 在每次迭代中创建一个新变量 j。
  2. 当前 i 值在迭代中分配给这个新的 j
  3. 这个新的 j 然后在同一迭代中绑定(bind)到 setTimeout 的函数。
  4. 下一次迭代会将新的 j 绑定(bind)到该迭代中的函数。

但结果是 j 绑定(bind)到所有迭代的最后一个 i 值。

那么,使用函数参数创建变量和使用 var 创建变量有什么区别?

有错误请指出!提前致谢!


谢谢大家!我不知道 javascript 只有函数和全局范围!责怪其他教我这样做的语言 :P

最佳答案

The second one is using closure to preserve the value of i.

事实上,您看到的两种结果都是闭包工作方式的结果。您传递给 setTimeout 的两个函数都是闭包。

I think the first one should preserve the value as well, because:

the var j create a new variable j in each iteration.

不,它没有。在您的第一个示例中只有 一个 j。在 JavaScript 中(目前),变量具有函数或全局作用域,从不阻塞作用域。 JavaScript 实际上对您的第一个示例执行的操作看起来更像这样:

var i;
var j;

for(i=0;i<10;i+=1){
j=i;
setTimeout(function(){
console.log(j);
},100);
}

生成的闭包有一个 持久引用 到那个 j 变量,这就是为什么你一遍又一遍地得到相同的值。

您的第二个示例有点反模式,因为它既难以阅读,又在每个循环中不必要地创建和丢弃函数。让我们通过添加一些变量使其更明显;此代码与您的第二个示例完全做同样的事情,唯一的变化是我添加的中间变量:

for(var i=0;i<10;i+=1){
var f1 = function(j){
var f2 = function(){
console.log(j);
};
setTimeout(f2,100);
};
f1(i);
}

相反:

for(var i=0;i<10;i+=1){
setTimeout(makeHandler(i));
}

function makeHandler(j){
return function(){
console.log(j);
};
}

既更易于阅读,又避免了在每个循环中重新创建 makeHandler 函数。

更多探索(在我的博客上):

关于Javascript变量复制范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20500098/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com