如何在循环外移动函数

时间:2013-07-15 14:47:34

标签: javascript

JSHint正在尖叫,应该在循环之外声明函数,我只是对如何做到这一点感到困惑?具体部分:self.onchange = function(){...}

这是循环:

for ( var j = 0; j < checkz.length; j++ ) {
    var self = checkz[j];
    self.onchange = function () {
        for ( var z = 0; z < psswrd.length; z++ ) {
            psswrd[z].type = self.checked ? 'text' : 'password';
        }
    };
}

当我将它移到外面并分配它时,该功能会因为'self'变得不确定而中断。任何建议表示赞赏。

1 个答案:

答案 0 :(得分:10)

在这种情况下,您只需要一个功能:

for ( var j = 0; j < checkz.length; j++ ) {
    var self = checkz[j];
    self.onchange = changeFunction;
    // Or replace the above two lines with:
    // checkz[j].onchange = changeFunction;
    // ...if you don't need `self` for anything else.
}

function changeFunction() {
    for ( var z = 0; z < psswrd.length; z++ ) {
        psswrd[z].type = this.checked ? 'text' : 'password';
        //               ^^^^--- note this changed from `self` to `this`
    }
}

您需要self =&gt;无论如何this会发生变化,因为最初的所有功能都会引用self相同值。在创建函数时,它对创建它的上下文中的变量有持久的引用,而不是在创建它时的值的副本。 (更多:Closures are not complicated)在这种情况下,我们可以使用this因为在一个事件处理程序中以这种方式连接(以及大多数方式),this将是事件处理程序被挂钩的元素最多。


现在在一般情况下,有时你需要引用循环中正在发生变化的东西而你碰巧没有替换它的方便,你通常会使用一个返回要使用的函数的构建器函数,像这样:

for ( var j = 0; j < checkz.length; j++ ) {
    var self = checkz[j];
    self.onchange = buildChangeFunction(j);
}

function buildChangeFunction(jarg) {
    return function() {
        // Use jarg in here...
    };
}

这样,我们分配给onchange的函数会关闭buildChangeFunction的参数,而不是j,并且该参数不会更改。

但同样,你不需要这个,上面的第一个解决方案就是你所需要的。