jQuery的.append():奇怪的行为

Epo*_*poc -2 jquery dom append

我用.append()jQuery 的方法面对一个奇怪的行为.

var container = $('#container');


var buttons = {
    'Okay': function() {
        return 'Yeah, I\'m okay with this.';
    },
    'Nope': function() {
        return 'No, no, definitively no.';
    },
    'Maybe': function() {
        return 'Hum, maybe.';
    }
};


for(var button_label in buttons) {
    var button_callback = buttons[button_label];

    var button_html = $('<button type="button">' + button_label + '</button>');

    button_html.on('click', function() {
        alert('button : ' + $(this).text() + ', callback : ' + button_callback());
    });

    container.append(button_html);
}
Run Code Online (Sandbox Code Playgroud)

查看JS Bin上的代码

一切正常,但是,正如您所看到的,当单击所有按钮时:调用相同的回调(最后在buttons对象中定义).我检查了jQuery的doc,也许这是相关的:

但是,如果存在多个目标元素,则将在第一个目标元素之后为每个目标创建插入元素的克隆副本.

或者,我需要重构我的代码.我测试了不同的解决方案,但都没有.有人可以帮帮我吗?

Thi*_*ter 5

这是传递给回调的循环中的一个好的"变量"问题,它存在于Stack Overflow上十亿次.所以它根本与jQuery无关.

您需要做的是在每个循环期间创建一个新变量.最简单的方法是使用立即执行的匿名函数并将值作为参数接收.

(function(button_callback) {
    button_html.on('click', function() {
        alert('button : ' + $(this).text() + ', callback : ' + button_callback());
    });
})(button_callback);
Run Code Online (Sandbox Code Playgroud)

更新了JSBin

为什么这有必要?在JavaScript中没有块范围.只有函数才能创建新范围.因此,在原始代码var button_callback中将提升到范围的顶部(包含循环的函数或全局范围,如果没有).所以在每次迭代中你都有相同的变量.并且此变量绑定到匿名函数的闭包.因此在循环之后变量具有最后一个值 - 在所有三个函数中.