【问题标题】:String doesn’t seem to be passed by value [duplicate]字符串似乎不是按值传递的[重复]
【发布时间】:2011-11-10 10:41:07
【问题描述】:

我使用以下函数将某个类的所有成员绑定到更改当前页面的函数。函数如下:

function _bind_menu_items() {
    var menuItems = fja.getElementsByClass("menuItem"),
        index,
        elementID,
        divIdToBind;

    for (index in menuItems) {
        elementID = menuItems[index].id;
        divIdToBind = elementID.replace("Item", "");

        menuItems[index].onclick = function() {
            fja.menu.changeActivePage(divIdToBind);
        };
    }
}

我已经检查了一切都按预期工作,直到 onclick 属性的实际分配。我得到的错误是属于 menuItem 类的每个 div 似乎都调用了相同的 onclick 函数......好像 divIdToBind 字符串对于分配的每个 onclick 都是完全相同的......我该如何解决这个问题?

【问题讨论】:

  • 您的所有点击事件处理程序都引用相同的divIdToBind 变量(您正在循环中创建一个函数)。这是一个相当普遍的问题。搜索 javascript loops closures 并查看 Closures for Dummies(示例 5)
  • @Thilo:感谢您找到这个。我一直在寻找这种情况的良好副本。这个好像够用了。

标签: javascript


【解决方案1】:

Javascript 初学者的第一个错误。你错过了绑定到onclick 处理程序的匿名函数,关闭它的父上下文。由于来自同一个父上下文的所有闭包共享同一个作用域链,所有这些函数都将引用传递给divIdToBind的最后一个值。

要解决这个问题,最常见的解决方法是创建另一个函数(-context):

menuItems[index].onclick = (function(id) {
    return function() {
        fja.menu.changeActivePage(id);
    };
}(divIdToBind));

现在我们确实创建了另一个立即执行的函数。我们将 divIdToBind 的值传递给它,它所做的只是返回另一个函数(只是为了创建一个新的上下文)

【讨论】:

    猜你喜欢
    • 2016-03-10
    • 2012-05-02
    • 2021-07-04
    • 1970-01-01
    • 2016-03-26
    • 2017-02-25
    • 2015-01-12
    • 2011-08-18
    • 2016-07-12
    相关资源
    最近更新 更多