为什么我需要复制一个数组才能使用它的方法?

cha*_*ham 28 javascript arrays

我可以使用Array()一个具有固定数量的未定义条目的数组.例如

Array(2); // [empty × 2] 
Run Code Online (Sandbox Code Playgroud)

但是,如果我去使用map方法,比如说,在我的新数组上,条目仍未定义:

Array(2).map( () => "foo");  // [empty × 2] 
Run Code Online (Sandbox Code Playgroud)

如果我复制数组,那么map确实有效:

[...Array(2)].map( () => "foo");  // ["foo", "foo"]
Run Code Online (Sandbox Code Playgroud)

为什么我需要副本才能使用该阵列?

Cer*_*nce 51

当您使用Array(arrayLength)创建数组时,您将拥有:

一个新的JavaScript数组,其length属性设置为该数字(注意:这意味着arrayLength空插槽的数组,而不是具有实际未定义值的插槽).

该数组实际上不包含任何值,甚至不包含undefined值 - 它只是一个length属性.

当您将具有属性的可迭代对象扩展length到数组中时,扩展语法将访问每个索引并在新数组中设置该索引处的值.例如:

const arr1 = [];
arr1.length = 4;
// arr1 does not actually have any index properties:
console.log('1' in arr1);

const arr2 = [...arr1];
console.log(arr2);
console.log('2' in arr2);
Run Code Online (Sandbox Code Playgroud)

并且.map只映射属性实际存在于要映射的数组中的属性/值.

使用数组构造函数令人困惑.我建议使用Array.from,从头开始创建数组时 - 你可以传递一个带有length属性的对象,以及一个映射函数:

const arr = Array.from(
  { length: 2 },
  () => 'foo'
);
console.log(arr);
Run Code Online (Sandbox Code Playgroud)


小智 9

原因是数组元素未分配.请参阅此处描述的第一段....仅对已分配值的数组索引(包括undefined)调用callback.

考虑:

var array1 = Array(2);
array1[0] = undefined;

// pass a function to map
const map1 = array1.map(x => x * 2);

console.log(array1);
console.log(map1);
Run Code Online (Sandbox Code Playgroud)

输出:

Array [undefined, undefined]
Array [NaN, undefined]
Run Code Online (Sandbox Code Playgroud)

当打印阵列时,询问其每个元素.第一个被分配undefined,另一个是默认的undefined.

映射操作调用第一个元素的映射操作,因为它已经定义(通过赋值).它不会为第二个参数调用映射操作,只是传递出去undefined.