Javascript:how is';新阵列(4)和#x27;与Array.apply不同(null,{length:4})?

Javascript:how is';新阵列(4)和#x27;与Array.apply不同(null,{length:4})?,javascript,arrays,Javascript,Arrays,我想生成一个给定长度的空数组,并用一些数字填充它。生成具有四个连续数字元素的阵列的一种方法是: var x = Array.apply(null, {length: 4}).map(function(item, index){return index;}) 但是当我看到Array.apply(null,{length:4})时,我想我可以用newarray(4)替换它,但事实并非如此。进行快速测试会产生以下结果: >> console.log((new Array(4))) <

我想生成一个给定长度的空数组,并用一些数字填充它。生成具有四个连续数字元素的阵列的一种方法是:

var x = Array.apply(null, {length: 4}).map(function(item, index){return index;})
但是当我看到
Array.apply(null,{length:4})
时,我想我可以用
newarray(4)
替换它,但事实并非如此。进行快速测试会产生以下结果:

>> console.log((new Array(4)))
<< [ <4 empty items> ]

>> console.log(Array.apply(null, {length: 4}))
<< [ undefined, undefined, undefined, undefined ]
console.log((新数组(4))) >log(Array.apply(null,{length:4})) 区别在于
新阵列(4)
不会初始化阵列中的插槽。它仅设置数组的长度属性。其中as
Array.apply(null,{length:4})
将每个插槽初始化为未定义。

apply
将上下文作为第一个参数,将类似数组的参数列表作为第二个参数。然后它调用函数(
Array
),将iterable作为参数

Array.apply(null, [1, 2])
// Same as
Array(1, 2)
// Or
[1, 2]
现在,如果您将一个对象作为arraylike传递,它仍然会像这样迭代它:

function apply(context, args) {
  for(var i = 0; i < args.length; i++) { 
    /*...*/ args[i];
  }
}
因此,数组插槽不是空的,而是未定义的,因为
map
只跳过空插槽,它将遍历第二个数组的每个条目

顺便说一句,同样的方法也可以实现得更具可读性:

Array.from({length: 4 }, (_, i) => i)
// [0, 1, 2, 3]

答案需要深入研究
Array
对象的机制

新建数组(4)
创建长度为4但没有项目的数组(稀疏数组)

Array.apply(null,{length:4})
创建一个包含4个未定义元素的数组

第二种方法使用了一些技巧:

  • apply
    使用数组中提供的给定上下文和参数调用函数

  • Array
    ,当作为函数直接调用时,将从作为参数获取的元素创建数组,例如:

    \>数组(1,2,3)
    [ 1, 2, 3 ]
    \>数组(…[1,2,3])
    [ 1, 2, 3 ]
    \>数组(…新数组(4))
    [未定义,未定义,未定义,未定义]

  • 那么为什么
    Array.apply(null,{length:4})
    等同于
    Array.apply(null,新数组(4)

    apply
    通过查看长度,然后获取相关参数来解析参数数组。
    {length:4}。length
    为4,因此需要

    {length:4}[0]
    {length:4}[1]
    {length:4}[2]
    {length:4}[3]
    

    这些都是未定义的

    这似乎效率很低,因为它创建了一个新数组。有什么问题吗?操作的结果应该可以清楚地看出它们之间的区别。您是否要求参考规范?
    {length:4}[0]
    {length:4}[1]
    {length:4}[2]
    {length:4}[3]