值由于引用访问而被覆盖

Value gets overwritten because of access by reference

本文关键字:访问 覆盖 引用 于引用      更新时间:2023-09-26
a = [];
for (var i = 0; i < 3; i++) {
   a.push(function() {
      console.log(i);
   })
}
a[0]()     // I want 0, but I get 3

我试着写一段简单的代码,我有一个函数数组,这样当我在一个特定的索引处执行一个函数时,索引值应该被打印出来。

但是,上面的代码段对所有索引值显示相同的结果(在本例中为3)。我知道值是通过引用指向的,因此指向I的最后一个值。有人能指出如何以正确的方式做到这一点吗?

将其包裹在函数周围。现在每次循环执行时,包装器函数都有自己的值i

a = [];
for (var i = 0; i < 3; i++) {
    (function(i){
        a.push(function() {
            console.log(i);
        })
   })(i);
}
a[0]() 

您可以添加一个自执行函数来充当模块。这样做,变量i的作用域在该函数中。

a = [];
for (var i = 0; i < 3; i++) {
   (function(i){
       a.push(function() {
           alert(i);
       })
   })(i);
}
a[0]() 

注:在此块(function(i){ ... })(i), i可以有任何名称, i from loop i from function之间没有联系,即(function(r){ ... })(r)

这是一个匿名函数的替代版本,它被一次创建并执行。

你遇到的问题是,当函数被调用时,循环已经被评估,i的值已经达到3的最大值。在执行循环时,需要捕获i的当前值。

var a = [];
for (var i = 0; i < 3; i++) {
  var fn = function() {
    console.log(arguments.callee.i);
  }
  fn.i = i; // Pass as 'i' parameter to 'fn'.
  a.push(fn);
}
a[0](); // The value 0 will be printed, rather than 3.

剥猫皮的方法不止一种。上面的代码非常类似于:

var a = [];
function fn(i) {
  return function() {
    console.log(i);
  }
}
for (var i = 0; i < 3; i++) {
  a.push(fn(i));
}
a[0](); // The value 0 will be printed, rather than 3.