[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);