在内部JavaScript函数中包含外部对象

时间:2012-08-25 06:34:18

标签: javascript html

我发现了一些似乎与此有关的问题,但在我的理解范围内,我的不同,所以这里有。 我已经大大简化了我的代码,甚至用注释替换了一行,但概念是相同的......

function myFunction(options) {
    var button;
    options.widgets.forEach(function (w) {
        button = document.createElement("button");
        //add button to the DOM
        aListOnMyPage.addEventListener("selectionchanged", function (args) {
            var a = button;
        });
    });
}

因此,对于每个小部件,我创建一个新对象,然后在页面上的列表中添加一个事件侦听器,该函数需要引用我创建的DOM元素(按钮)。 我看到的行为是我的按钮被正确设置在我创建事件监听器的位置,但是当监听器的事件触发时,按钮始终是对我创建的最后一个按钮的引用。 也许这是因为它已经很晚了,但我无法理解为什么会这样做。谁能为我澄清这个?

2 个答案:

答案 0 :(得分:3)

当然可以。

这里的问题实际上是范围。我们来看看你写的代码:

function myFunction(options) {
    var button;
    options.widgets.forEach(function (w) {
        button = document.createElement("button"); // UH-OH...
        //add button to the DOM
        aListOnMyPage.addEventListener("selectionchanged", function (args) {
            var a = button;
        });
    });
}

注意呃哦?您已声明button应该等于document.createElement("button"),但由于您未使用var关键字,因此您已声明了一个全局变量,而不是多个本地变量。这意味着每次循环运行时,侦听器都会引用一个全局变量,这会导致您的问题。

确保在这里使用局部变量,如下所示:

function myFunction(options) {
    options.widgets.forEach(function (w) {
        var button = document.createElement("button"); 
        //add button to the DOM
        aListOnMyPage.addEventListener("selectionchanged", function (args) {
            var a = button;  
        });
    });
}

这应该会大大改善你的情况。至少,我希望它能帮助你更进一步。祝你好运。

答案 1 :(得分:1)

我认为你因为闭包而面临这个问题,你myFunction中使用的按钮变量是相同的,所有更改都是引用更改,所以我认为将变量的声明更改为匿名函数内部应该解决这个问题。

function myFunction(options) {
    //var button;
    options.widgets.forEach(function (w) {
        var button = document.createElement("button");
        //add button to the DOM
        aListOnMyPage.addEventListener("selectionchanged", function (args) {
            var a = button;
        });
    });
}

此更改在forEach中为匿名函数提供了单独的button变量。