JavaScript:包含函数数组的TypeError

时间:2013-03-26 04:09:39

标签: javascript arrays function closures typeerror

所以今天我开始乱用JavaScript,我遇到了一个有趣的案例,它似乎确信某些东西是一个功能,同时也确信它不是一个功能。此代码说明了此问题:

var arr1 = Array(1)
for (i = 0; i < arr1.length; i++) {
    arr1[i] = function(n) { return n + i }
}

var arr2 = Array(1)
for (j = 0; j < arr2.length; j++) {
    arr2[j] = function(n) { return arr1[j](n) }
}

typeof arr2[0] // "function"
arr2[0](2)     // TypeError: Property '1' of object [object Array] is not a function

从此处,您可以将变量分配给arr2[0],并且错误仍然存​​在。我不确定是否需要闭包或数组来复制它。

我的代码是否有些东西,或者这只是JavaScript奇怪之一?这不是我特别需要回答的问题,但它有点傻,所以我想知道是否有理由。

4 个答案:

答案 0 :(得分:3)

这实际上确实与闭包有关。

首先,请使用此代码:

for (j = 0; j < arr2.length; j++) {
    arr2[j] = function(n) { return arr1[j](n) }
}

变量j最初保持值0,因此arr2[0]设置为对函数的引用。

接下来,j递增,现在值为1.这将终止循环。

现在,调用函数时

return arr1[j](n)

由于闭包,j的最终值仍为1.这是该数组中的无效索引。

还有一点需要指出。 for循环不会创建新的闭包,因此如果您希望匿名函数在该迭代中包含 j的值,那么该假设是错误的。在声明j的整个函数中将有一个j实例。

答案 1 :(得分:1)

我认为你试图在循环中使用闭包,但它不能那样工作。

如果你想在循环的每一步中使用ij的值,你可以使用匿名函数,如下所示。

var arr1 = Array(1)
for (i = 0; i < arr1.length; i++) {
    arr1[i] = (function(i){
        return function(n) { 
            return n + i 
        };
    })(i);
}

var arr2 = Array(1)
for (j = 0; j < arr2.length; j++) {
    arr2[j] = (function(j){
        return function(n) { 
            return arr1[j](n)
        }
    })(j);
}

typeof arr2[0] 
arr2[0](2)

演示:Fiddle

答案 2 :(得分:0)

它没有做任何奇怪的事情。

你只是尝试一些不是函数的东西(arr1[1]的值,即undefined)。

答案 3 :(得分:0)

以下列形式初始化数组可能更安全:

var arr1 = [];

或者如果你正在使用'Array',你应该像这样初始化它:

var arr1 = new Array();