1

鉴于此函数调用:

var funcs = obj.getClosures([2, 4, 6, 8], function(x) {
    return x*x;
});

我有以下功能:

getClosures : function(arr, fn) {
    var funcs = [];
    var array = arr;
    var i = 0;
    var l = array.length;

    (function(i, array) {

        for (; i < l; i++) {
            funcs[i] = function(i, array) {
                return fn(array[i]);
            };
        }

    }(i, array));

    return funcs; 

},

我希望能够遍历返回的数组并获得数组中每个项目的平方根值,就像这样:

for (var i = 0; i < arr.length; i++) {
   funcs[i]();
}

每次循环的结果:4、16、36、64

我的 funcs 数组不应该在每个索引中都有一个可以使用相关参数值轻松调用的函数引用吗?我哪里做错了?

4

2 回答 2

2

有多个“问题”:

IIFE(function(i, array) { ... }(i, array));在这里根本没有任何好处。如果您删除它,代码将具有完全相同的行为。如果要捕获 and 的当前值iarray则必须将其移动到循环内。for

您的函数定义不正确。

funcs[i] = function(i, array) {
    return fn(array[i]);
};

在函数内部,array[i]将引用您传递给函数的参数。如果您不通过,它们将是undefined并且代码将引发错误。也就是说,使用该定义,您必须像这样执行函数:

for (var i = 0; i < arr.length; i++) {
   funcs[i](i, array);
}

哪种方式首先破坏了生成功能的目的。

如果要创建一个可以访问iarray定义函数的范围的闭包,请不要定义具有相同名称的参数。

可能的解决方案:

for (var i = 0, l = array.length; i < l; i++) {
    (function(i) {
        funcs[i] = function() {
            return fn(array[i]);
        };
    }(i));
}

或者更简单,如果您的代码在支持的环境中运行.map

getClosures: function(arr, fn) {
    return arr.map(function(v) {
        return function() {
            fn(v);
        };
    });
},

相关问题:

于 2013-06-29T10:57:53.577 回答
0

阅读Function.prototype.bind

var obj = {
getClosures : function(arr, fn) {
     var funcs = [];
    var array = arr;
    var i = 0;
    var l = array.length;

    (function(i, array) {

        for (; i < l; i++) {
            funcs[i] = function(i, array) {
                return fn(array[i]);
            }.bind(this,i,array);
        }

    }(i, array));

    return funcs; 

}
}

var funcs = obj.getClosures([2, 4, 6, 8], function(x) {
    return x*x;
});

for (var i = 0; i < funcs.length; i++) {
   console.log(funcs[i]());
}

输出:

4
16
36
64

它从 javascript 1.8.5 (firefox 4) 开始工作。我不知道其他浏览器,但有旧版本的实现(也应该在旧浏览器上工作)

于 2013-06-29T11:11:10.623 回答