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

在内部JavaScript函数中包含外部对象,javascript,html,Javascript,Html,我发现了一些似乎与此相关的问题,但在我的理解范围内,我的问题是不同的,所以这里是。 我已经大大简化了我的代码,甚至用注释替换了一行,但概念是一样的 function myFunction(options) { var button; options.widgets.forEach(function (w) { button = document.createElement("button"); //add button to the DOM

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

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;
        });
    });
}
注意到了吗?您已经声明
按钮
应该等于
document.createElement(“按钮”)
,但是由于您没有使用
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;  
        });
    });
}
这将大大改善你的处境。至少,我希望它能帮助你更进一步。祝你好运。

当然可以

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

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;
        });
    });
}
注意到了吗?您已经声明
按钮
应该等于
document.createElement(“按钮”)
,但是由于您没有使用
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;
        });
    });
}

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

我认为您正面临此问题,因为闭包,在整个过程中使用的按钮变量与
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
中的匿名函数提供了单独的
按钮
变量。

搜索“javascript循环最后值”或类似值。例如,etc是以稍微不同的形式出现的相同问题。搜索“javascript循环最后一个值”或类似内容。例如,etc是以稍微不同的形式出现的同一个问题。关于闭包,你是正确的,但关于按钮的全局性,你不是正确的。在OP中,它是外部函数的局部。实际上,在简化代码时,我删除了循环外部的var按钮,因此它不是全局的,但这正是我的问题。我想我把这当成一个了结的问题太难了。谢谢,@午餐317!!关于闭包,你是对的,但关于按钮的全局性,你是错的。在OP中,它是外部函数的局部。实际上,在简化代码时,我删除了循环外部的var按钮,因此它不是全局的,但这正是我的问题。我想我把这当成一个了结的问题太难了。谢谢,@午餐317!!不需要a变量,监听器中的按钮与外部“each”函数中声明的按钮有一个闭包,因此可以直接使用。我知道,我只是尽量使代码与他的代码更接近。不需要a变量,监听器中的按钮与外部“each”函数中声明的按钮有一个闭包我知道,我只是尽量让代码对他的代码保持微笑。