【问题标题】:JavaScript: TypeError with array of functionsJavaScript:带有函数数组的 TypeError
【发布时间】:2013-03-15 18:52:07
【问题描述】:

所以我今天开始乱用 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 中的一个古怪之处?这不是我特别需要回答的问题,但有点愚蠢,所以我想知道是否有原因。

【问题讨论】:

  • 为什么是Array(1) 和一个循环而不是var arr1 = [function(n) { return n + 1;}];
  • 这最初是在我在循环索引上试验闭包数组时发生的,所以我就保持这样
  • 另外,@bfavaretto:这就像我最初测试的那样,结果证明它比我想象的更多(因为每个的基本原理是相同的)。所以我愿意承认这是重复的。

标签: javascript arrays function closures typeerror


【解决方案1】:

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

首先,获取以下代码:

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 实例。

【讨论】:

  • 啊,这是有道理的(而且我了解到越界索引返回undefined 而不是抛出错误)。感谢您的快速答复。
  • 是的,数组就像任何其他对象一样变成了属性包。如果你愿意,没有什么能阻止你设置 arr2[50]arr2['bananas']
【解决方案2】:

我认为您正在尝试在循环内使用闭包,但它不会那样工作。

如果您想在循环的每一步中使用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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

      var arr1 = [];
      

      或者如果你使用“数组”,你应该像这样初始化它:

      var arr1 = new Array();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-09
        • 1970-01-01
        • 1970-01-01
        • 2019-10-25
        • 2021-10-17
        • 1970-01-01
        • 1970-01-01
        • 2021-06-05
        相关资源
        最近更新 更多