JavaScript:TypeError与函数数组

JavaScript:TypeError与函数数组,javascript,arrays,function,closures,typeerror,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] = fu

所以我今天开始胡乱使用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
var arr1=数组(1)
对于(i=0;i
从这里,您可以为
arr2[0]
分配一个变量,并且错误仍然存在。我不确定是否需要闭包或数组来复制它


我的代码是否有问题,或者这只是JavaScript的一个奇怪之处?这不是我特别需要的答案,但它有点傻,所以我想知道这是否有原因。

它没有做任何奇怪的事情


您只是尝试创建非函数的内容(arr1[1]
的值,它是未定义的。

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

var arr1 = [];
或者,如果您使用的是“数组”,则应按如下方式初始化它:

var arr1 = new Array();
这实际上与闭包有点关系

首先,以以下代码为例:

for (j = 0; j < arr2.length; j++) {
    arr2[j] = function(n) { return arr1[j](n) }
}
由于闭包,
j
的最终值仍然为1。这是该数组中的无效索引


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

我认为您试图在循环中使用闭包,但它不是这样工作的

如果要在循环的每个步骤中使用
i
j
的值,必须使用如下所示的匿名函数

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)
var arr1=数组(1)
对于(i=0;i

演示:

为什么
Array(1)
和一个循环而不是
var arr1=[函数(n){returnn+1;}]?这可能重复最初发生在我在循环索引上试验闭包数组时,所以我也这样保持它,@bfavaretto:这与我最初测试的结果类似,结果证明它与此有着比我想象的更多的关系(因为每种方法的基本原理都是相同的)。所以我愿意承认这是一个重复。啊,这是有道理的(而且我知道越界索引返回
未定义的
,而不是抛出错误)。感谢您的快速回答。是的,数组就像其他任何对象一样成为财产袋。如果您愿意,没有什么可以阻止您设置
arr2[50]
arr2['bananas']
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)