返回一组函数:创建闭包

时间:2013-06-29 10:46:48

标签: javascript function closures

给定此函数调用:

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数组不应该在每个索引中都有一个函数引用,可以使用相关的参数值轻松调用吗?我哪里出错了?

2 个答案:

答案 0 :(得分:2)

有多个“问题”:

IIFE (function(i, array) { ... }(i, array));在这里完全没有任何好处。如果删除它,代码将具有完全相同的行为。如果要捕获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);
        };
    });
},

相关问题:

答案 1 :(得分: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)。我不知道其他浏览器,但有旧版本的实现(也应该适用于旧浏览器)