通过引用值来代替JavaScript闭包 - 任何非包装技术?

时间:2013-11-11 15:14:20

标签: javascript closures

通过引用传递给闭包的变量。这段代码:

var figs = ['circle', 'square'];
for (var i in figs) {
    var fig = figs[i];
    document.getElementById(fig).addEventListener("click", function(e) {
        console.log(fig);
    }, false);
}

总是记录最后一个数组元素,即使你点击 circle square fig 变量的最后一个值)。

为了绑定 fig 变量的实际值,我在函数调用中使用包装(所以中间闭包保持循环值):

var figs = ['circle', 'square'];
for (var i in figs) {
    var fig = figs[i];
    document.getElementById(fig).addEventListener("click", (function(fig) {
        return function(e) {
            console.log(fig);
        }
    })(fig), false);
}

是否可以避免包装函数以传递值?

更新相关问题和答案:

2 个答案:

答案 0 :(得分:4)

不,这是不可能的。

但是,通过从循环中获取生成内部函数的代码,可以使代码更好一些:

var figs = ['circle', 'square'];
function createFigHandler(fig) {
    return function(e) {
        console.log(fig);
    }
}

for (var i = 0; i < figs.length; i++) {
    var fig = figs[i];
    document.getElementById(fig).addEventListener("click", createFigHandler(fig), false);
}

jsFiddle

答案 1 :(得分:2)

您还可以使用bind并传递一个封装所需变量的对象。然后,您可以在处理程序中使用this.fig来引用您的图形。

document.getElementById(fig).addEventListener("click", (function(e) {
     console.log(this.fig);
}).bind({ fig: fig }), false);

您也可以直接绑定原始值,但是它将包含在它的相应对象包装器中,例如Number代表一个数字,String代表一个字符串,等等。

document.getElementById(fig).addEventListener("click", (function(e) {
    //this will be the same as new String(fig)
}).bind(fig), false);