因为每个'new Array'都没有做我期望的事情



我只是在学习如何使用JS高阶函数(map、forEach、reduce等),却陷入了困惑。我试图编写一个简单的"range"函数,但似乎无法填充我的输出数组。这就是目标:

range(1, 4) // [1, 2, 3, 4]

我得到这个:

[undefined × 4]

这是我的代码:

 function range(num1, num2) {
      var rangeArr = new Array((num2 + 1) - num1);
      return rangeArr.map(function(e, i, arr) {return arr[i] = num1 + i});
    }

我在这里错过了什么?据我所知,这个问题似乎与我使用"新阵列"的方式有关,但除此之外,我迷失了方向。

哦,这是真正让我困惑的部分。这很好:

function bleck() {
    var blah = [1, 2, 3, 4];
    var x = 'wtf';
    return blah.map(function(e, i, arr) {return arr[i] = x})
}
["wtf", "wtf", "wtf", "wtf"]

谢谢!!

forEach方法迭代数组的索引。有趣的是,当您通过new Array(n)创建一个新数组时,它根本不包含索引。相反,它只是设置其.length属性。

> var a = new Array(3);
> console.info(a)
[]
> console.info([undefined, undefined, undefined])
[undefined, undefined, undefined]

MDN描述了forEach,并特别指出:

forEach为具有指定值的数组。对于具有已被删除或消除。

这里有一种巧妙的技术,可以获得一个索引为空但存在的数组。

var a = Array.apply(null, Array(3));

这是因为.apply将消隐元素"扩展"为适当的参数,结果与Array(undefined, undefined, undefined)类似。

数组由4个整数定义,每个整数都未定义。

Map不会迭代未定义的实体,而是跳过它们。

回调仅对已分配的数组的索引调用价值观对于未定义的索引,即已被删除或从未分配过值。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

当您创建一个new Array(x)时,它正在创建一个所谓的稀疏数组,它的行为可能有点不同,正如您所看到的,如果您只设置一个值,一些浏览器会说[undefined x 20,"foo", undefined x 5],我相信它不会迭代这些值。

问题是map不会迭代未定义的条目(*)。

我建议使用for循环:

var rangeArr = new Array((num2 + 1) - num1);
for(var i=0; i<=num2-num1; ++i)
    rangeArr[i] = num1 + i;
return rangeArr;

(*)对于未定义的条目,我的意思是rangeArr.hasOwnProperty(i) === false,不要与rangeArr[i] === void 0混淆。

最新更新