可变变量的 JS 闭包

JS closure for mutable variables

请帮我找出局部"j"变量在循环中不断变化的原因:

var a1 = a2 = a3 = {};

for (var i = 1; i < 4; i ++ ) {
  (function(j){
    console.log(j);
    window['a'+j].fu = function(){
      console.log('fu:',j);
    };
  })(i);

}

a1.fu(); // returns "fu:,3" - why not 1?

a2.fu(); // returns "fu:,3" - why not 2?

a3.fu(); // returns "fu:,3"

我阅读了关于类似问题的很好的回答,但它不适用于我的情况。 Mutable variable is accessible from closure. How can I fix this?

对象赋值不复制对象,三个变量都引用同一个对象。因此,即使更改循环内的值也会为不同的对象更新相同的位置。

对象中的值在循环的最后一次迭代中设置为 3,在 for 循环后检索值时,所有变量都返回值 3。

创建对象时

var a1 = a2 = a3 = {};

三个变量都指向同一个对象。

问题的解决方法是单独声明对象。

var a1 = {},
    a2 = {},
    a3 = {};

for (var i = 1; i < 4; i++) {
  (function(j) {
    console.log(j);
    window['a' + j].fu = function() {
      console.log('fu:', j);
    };
  })(i);
}

a1.fu(); // returns "fu:,3" - why not 1?

a2.fu(); // returns "fu:,3" - why not 2?

a3.fu(); // returns "fu:,3"

您将 a1a2a3 分配给同一对象的方式意味着 它们都是同一事物的不同名称,即它们都引用同一个对象。

您的 for 循环然后运行三次,创建三个匿名函数。在每个函数中,j 具有不同的值,因此您会期望 运行 这些函数在您调用 fu().

时显示三个不同的值

但是,因为a1a2a3都是一样的,循环的每次迭代都会覆盖前面的fu(),直到您只剩下 j 的嵌入值为 3.

的那个

运行 赋值不同的代码,观察行为如何改变为您最初的预期:

var a1 = {};
var a2 = {};
var a3 = {};

将每个变量视为指向对象的指针: var a = b = c = {}; 等于:

a
 \
  \
b-- {}
  /
 /
c

您没有使用同一个变量来访问对象,而是每次都修改同一个对象。

尝试:

a.test = 'fromA';
console.log(b.test); //fromA
console.log(c.test); //fromA