在for循环Javascript中维护引用

时间:2013-08-02 17:19:14

标签: javascript for-loop reference

我有以下代码:

for(var i = 0; i < nodelist.length; i++) {
    var x = functionThatCreatesADivElement();

    someElement.appendChild(x.getDiv());  // this works fine

    nodelist[i].onclick = function() {
       x.someFunction();                  // this always refer to the last 'x' object
    }
}


function functionThatCreatesADivElement() {
   var div = document.createElement("div");

   this.someFunction = function() {}

   this.getDiv = function() {
      return div;
   }

   return this;
} 

问题是nodelist[0].onclick的执行与nodelist[4].onclick完全相同(假设i = 4是最后一个节点)。

我相信先前迭代的引用正在改变为指向当前迭代的元素。

这样做的正确方法是什么?

编辑:添加了一些代码并更改了函数的名称,因为它太混乱了

2 个答案:

答案 0 :(得分:1)

你有两个问题。第一个问题是JavaScript变量没有块范围。

来自MDN

  

当您在任何函数之外声明变量时,它被称为全局变量,因为它可用于当前文档中的任何其他代码。声明变量时   在函数内,它被称为局部变量,因为它只在其中可用   功能

     

JavaScript没有块语句范围;

您没有在函数中包含x变量,因此所有onclick回调都使用相同的x变量,该变量指向循环中的最后一个元素,因为那样是最后一个被覆盖x的人。

为循环执行此操作应该有效:

nodelist.forEach(function (nodeitem) {
    var x = functionThatCreatesADivElement();

    someElement.appendChild(x.getDiv());

    nodeitem.onclick = function() {
        x.someFunction();
    }
});

第二个问题是未正确调用functionThatCreatesADivElement()构造函数。因为您正在调用构造函数,所以请使用new functionThatCreatesADivElement()

答案 1 :(得分:0)

解决。我不得不使用

var x = new functionThatCreatesADivElement();

function functionThatCreatesADivElement() {
   var div = document.createElement("div");

   this.someFunction = function() {}

   this.getDiv = function() {
      return div;
   }

   //return this;  //Using new instead of returning this

}