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

Including outer object in inner JavaScript function

本文关键字:对象 包含外 JavaScript 函数 在内部      更新时间:2023-09-26

我发现了一些似乎与此有关的问题,但从我的理解来看,我的问题有所不同,所以到此为止。我已经大大简化了我的代码,甚至用注释替换了其中一行,但概念是一样的。。。

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元素(按钮)。我看到的行为是,我的按钮在创建事件侦听器时被正确设置,但当侦听器的事件触发时,按钮始终是我创建的最后一个按钮的引用。也许是因为太晚了,但我无法理解为什么会这样。有人能帮我澄清一下吗?

当然可以。

你的问题实际上是范围。让我们看看您编写的代码:

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;  
        });
    });
}

这将大大改善你的处境。至少,我希望它能帮助你更进一步。祝你好运。

我认为您面临这个问题是因为闭包,在整个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;
        });
    });
}

此更改为CCD_ 5中的匿名函数提供了单独的CCD_。