简体   繁体   English

可变变量的JS闭包

[英]JS closure for mutable variables

Please help me find the reason why the local "j" variable continues to change during the loop: 请帮助我找出循环期间本地“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"

I read the nice answer on similar issue, but it's not working for my case. 我在类似的问题上阅读了很好的答案,但这不符合我的情况。 Mutable variable is accessible from closure. 可以通过闭包访问可变变量。 How can I fix this? 我怎样才能解决这个问题?

Object assignment does not make copy of the objects, the same object is referenced by all the three variables. 对象赋值不会复制对象,所有三个变量都会引用相同的对象。 So, even changing the value inside the loop will update the same location for different object. 因此,即使更改循环内的值也会更新不同对象的相同位置。

The value in the object is set as 3 in the last iteration of the loop and when retrieving the value after for loop, the value 3 is returned for all the variables. 在循环的最后一次迭代中,对象中的值设置为3,并且在for循环后检索值时,将为所有变量返回值3。

When you create objects 创建对象时

var a1 = a2 = a3 = {};

all the three variables refer to the same object. 所有三个变量都指向同一个对象。

Solution to the problem can be declaring the object individually. 问题的解决方案可以单独声明对象。

 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" 

The way you assigned a1 , a2 , and a3 all to the same object means they are all different names for the same thing , ie they all reference the same object. a1a2a3 all分配给同一个对象的方式意味着它们对于同一个对象都是不同的名称 ,即它们都引用相同的对象。

Your for loop then runs three times, creating three anonymous functions. 你的for循环然后运行三次,创建三个匿名函数。 In each function, j has a different value, so you would expect running those functions to show three different values when you call fu() . 在每个函数中, j具有不同的值,因此当您调用fu()时,您希望运行这些函数以显示三个不同的值。

However , since a1 , a2 , and a3 are all the same, each iteration of the loop overwites the previous fu() , until you're left only with the one with the embedded value of j being 3 . 但是 ,由于a1a2a3都是相同的,所以循环的每次迭代都会覆盖前一个fu() ,直到你只剩下嵌入值为j3那个。

Run the code with different assignment, and watch how the behavior changes to what you were originally expecting: 运行具有不同赋值的代码,并观察行为如何更改为您最初期望的内容:

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

See every variable like a pointer to an object : var a = b = c = {}; 查看每个变量,如指向对象的指针: var a = b = c = {}; is equal to : 等于:

a
 \
  \
b-- {}
  /
 /
c

You don't use the same variable to access the object but you modify the same object every time. 您不使用相同的变量来访问对象,但每次都修改相同的对象。

try: 尝试:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM