[javascript] JavaScript“new Array (n)”및“Array.prototype.map”기묘함

Firefox-3.5.7 / Firebug-1.5.3 및 Firefox-3.6.16 / Firebug-1.6.2에서 이것을 관찰했습니다.

Firebug를 시작할 때 :

var x = new Array(3)
console.log(x) 
// [undefined, undefined, undefined]

var y = [undefined, undefined, undefined]
console.log(y) 
// [undefined, undefined, undefined]

console.log( x.constructor == y.constructor) // true

console.log( 
  x.map(function() { return 0; })
)
// [undefined, undefined, undefined]

console.log(
  y.map(function() { return 0; })
)
// [0, 0, 0]

무슨 일이야? 이것은 버그입니까, 아니면 사용 방법을 오해하고 new Array(3)있습니까?



답변

첫 번째 예는

x = new Array(3);

정의되지 않은 포인터로 배열을 만듭니다.

그리고 두 번째는 정의되지 않은 3 개의 객체에 대한 포인터가있는 배열을 만듭니다.이 경우 포인터 자체는 정의되지 않았으며 자신이 가리키는 객체 만 정의됩니다.

y = [undefined, undefined, undefined]
// The following is not equivalent to the above, it's the same as new Array(3)
y = [,,,];

배열이 객체의 컨텍스트에서 맵을 실행함에 따라 첫 번째 맵이 함수를 전혀 실행하지 못하는 반면 두 번째 맵은 실행되지 않습니다.


답변

배열의 길이 만 알고 항목을 변환 해야하는 작업이있었습니다. 나는 이런 식으로하고 싶었다 :

let arr = new Array(10).map((val,idx) => idx);

다음과 같이 신속하게 배열을 만들려면

[0,1,2,3,4,5,6,7,8,9]

그러나 다음과 같은 이유로 작동하지 않았습니다. (위의 몇 가지 답변을 Jonathan Lonowski의 답변 참조)

해결 방법은 Array.prototype.fill ()을 사용하여 배열 항목을 정의되지 않은 값으로 채울 수 있습니다.

let arr = new Array(10).fill(undefined).map((val,idx) => idx);

최신 정보

다른 해결책은 다음과 같습니다.

let arr = Array.apply(null, Array(10)).map((val, idx) => idx);

console.log(Array.apply(null, Array(10)).map((val, idx) => idx));


답변

ES6을 사용하면 [...Array(10)].map((a, b) => a)빠르고 쉽게 할 수 있습니다!


답변

ES6 솔루션 :

[...Array(10)]

그러나 typescript (2.3)에서는 작동하지 않습니다.


답변

배열이 다릅니다. 차이점은 new Array(3)길이는 3이지만 속성 [undefined, undefined, undefined]은없는 배열 을 만드는 반면 “0”, “1”및 “2”라는 길이는 3 및 3 개의 속성을 가진 배열 을 만드는 것입니다 undefined. in연산자를 사용하여 차이점을 볼 수 있습니다 .

"0" in new Array(3); // false
"0" in [undefined, undefined, undefined]; // true

이것은 JavaScript에서 네이티브 객체의 존재하지 않는 속성 값을 얻으 undefined려고하면 존재하지 않는 변수를 참조하려고 할 때 오류가 발생하지 않고 반환된다는 약간 혼란스러운 사실에서 비롯 됩니다 )는 속성이 이전에 명시 적으로로 설정된 경우와 동일합니다 undefined.


답변

MDC 페이지에서 map:

[…] callback는 값이 할당 된 배열의 인덱스에 대해서만 호출됩니다. […]

[undefined]실제로 인덱스 있도록 (들)에 세터를 적용 map하는 반면, 반복됩니다 new Array(1)단지가 기본값으로 인덱스 (들)을 초기화 undefined때문에 map건너 뛰고 그것.

나는 이것이 모든 반복 방법에 대해 동일하다고 믿는다 .


답변

ECMAScript 6 판 사양.

new Array(3)속성 만 정의 length하고 같은 색인 속성은 정의하지 마십시오 {length: 3}. https://www.ecma-international.org/ecma-262/6.0/index.html#sec-array-len 9 단계를 참조 하십시오 .

[undefined, undefined, undefined]같은 색인 속성과 길이 속성을 정의 {0: undefined, 1: undefined, 2: undefined, length: 3}합니다. https://www.ecma-international.org/ecma-262/6.0/index.html#sec-runtime-semantics-arrayaccumulation ElementList 5 단계를 참조 하십시오 .

방법 map, every, some, forEach, slice, reduce, reduceRight, filter에 의해 색인 속성 확인한다 어레이의 HasProperty내부 방법이므로 new Array(3).map(v => 1)하지 않습니다 콜백 호출한다.

자세한 내용은 https://www.ecma-international.org/ecma-262/6.0/index.html#sec-array.prototype.map을 참조 하십시오.

어떻게 고치는 지?

let a = new Array(3);
a.join('.').split('.').map(v => 1);

let a = new Array(3);
a.fill(1);

let a = new Array(3);
a.fill(undefined).map(v => 1);

let a = new Array(3);
[...a].map(v => 1);