JavaScript "new Array(n)" 및 "Array.protype.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)
배열 길이만 알고 아이템을 변환해야 하는 작업이 있었습니다.저는 이런 걸 하고 싶었어요.
let arr = new Array(10).map((val,idx) => idx);
다음과 같은 어레이를 빠르게 작성하려면:
[0,1,2,3,4,5,6,7,8,9]
그러나 이 방법은 다음과 같은 이유로 효과가 없었습니다. (아래에 있는 Jonathan Lonowski의 답변 참조)
해결책은 Array.protype.fill()을 사용하여 어레이 항목을 임의의 값(정의되지 않은 값도 포함)으로 채우는 것입니다.
let arr = new Array(10).fill(undefined).map((val,idx) => idx);
console.log(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));
첫 번째 예는
x = new Array(3);
길이가 3이지만 요소가 없는 배열을 만들기 때문에 [0], [1] 및 [2] 인덱스는 생성되지 않습니다.
두 번째는 정의되지 않은 3개의 객체로 배열을 만듭니다.이 경우 인덱스/속성은 직접 생성되지만 참조하는 객체는 정의되지 않습니다.
y = [undefined, undefined, undefined]
// The following is not equivalent to the above, it's the same as new Array(3)
y = [,,,];
맵은 설정된 길이가 아닌 인덱스/속성 목록에서 실행되므로 인덱스/속성이 생성되지 않으면 실행되지 않습니다.
ES6를 실행할 수 .[...Array(10)].map((a, b) => a)
,
ES6 솔루션:
[...Array(10)]
다만, 타이프 스크립트(2.3)에서는 동작하지 않는다.
의 MDC 페이지:
[...]
callback
[undefined]
는 실제로하여 "Setter" 가 "는 "Setter"map
만'은 '반복합니다.new Array(1)
「」로undefined
map
너뜁니니다다
나는 이것이 모든 반복 방법에서 같다고 믿는다.
어레이가 다르다. 점은 '하다'는 것입니다.new Array(3)
.한편, 3은 속성 없음입니다.[undefined, undefined, undefined]
가 " "및 "2각은 "0", "1", "2"는 "2"는 "0", "2"는 "2"는 "2"는 "2"는 "2"는 "2"는 "2"는 "2"는 "2"는 "2"는 "2"는 "2"의 값입니다.각 속성은 다음과 같습니다.undefined
이알 수 .in
★★★★★★★★★★★★★★★★★★:
"0" in new Array(3); // false
"0" in [undefined, undefined, undefined]; // true
하지 않는 JavaScript가 .undefined
하지 않는 변수를 할 때 보다는) 되어 있는 경우와 .undefined
.
다른 답변에서 충분히 설명되는 이유로,Array(n).map
동작하지 않습니다.그러나 ES2015에서는 다음과 같은 지도 기능을 사용할 수 있습니다.
let array1 = Array.from(Array(5), (_, i) => i + 1)
console.log('array1', JSON.stringify(array1)) // 1,2,3,4,5
let array2 = Array.from({length: 5}, (_, i) => (i + 1) * 2)
console.log('array2', JSON.stringify(array2)) // 2,4,6,8,10
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
는 Array의 인덱스 합니다.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);
이것을 설명하는 가장 좋은 방법은 Chrome의 처리 방식을 보는 것이라고 생각합니다.
>>> x = new Array(3)
[]
>>> x.length
3
따라서 실제로는 새로운 Array()가 값이 없는 3의 빈 배열을 반환하고 있습니다.<고객명>을 하면 <고객명>님이x.map
기술적으로 빈 어레이에서는 설정할 것이 없습니다.
는 빈을 Firefox로.undefined
치관가
나는 이것이 명백한 버그라고 생각하지 않는다. 단지 무슨 일이 일어나고 있는지를 표현하는 서투른 방법일 뿐이다.Chrome이 실제로는 어레이에 아무것도 없다는 것을 보여주기 때문에 Chrome이 "더 정확한 것 같습니다.
벌레가 아니라.어레이 컨스트럭터는 이렇게 정의되어 있습니다.
MDC에서:
배열 생성자를 사용하여 단일 숫자 매개 변수를 지정하는 경우 배열의 초기 길이를 지정합니다.다음 코드는 5가지 요소로 구성된 배열을 만듭니다.
var billingMethod = new Array(5);
배열 생성자의 동작은 단일 매개 변수가 숫자인지 여부에 따라 달라집니다.
.map()
method는 명시적으로 값이 할당된 배열의 반복 요소에만 포함됩니다. even assign assign an even even 、 、 even 、 [ ]undefined
값은 반복에 포함할 수 있는 것으로 간주됩니다.입니다.undefined
" " " 체체 、 " 락락 :
var x = { }, y = { z: undefined };
if (x.z === y.z) // true
'''」x
에는 "z "z"는 "z"입니다.또한 오브젝트는y
두 은 "", "값"은 "값"입니다.undefined
의 값은 과 같습니다.length
는 0 ~ 0 의 합니다.length - 1
. 。.map()
따라서 Array Constructor 및 숫자 인수를 사용하여 새로 구성된 배열에서 호출된 경우 함수는 아무것도 수행하지 않습니다(콜백을 호출하지 않음).
방금 이걸 만났어사용할 수 있으면 편리할 것 같습니다.Array(n).map
.
Array(3)
산출하다{length: 3}
[undefined, undefined, undefined]
는 번호부.번호부 속성을 만듭니다.
{0: undefined, 1: undefined, 2: undefined, length: 3}
.
map() 실장은 정의된 속성에만 적용됩니다.
어레이에 값을 쉽게 채우기 위해 브라우저 지원을 위해 fill을 사용할 수 없고 for-loop을 실행하고 싶지 않은 경우 다음 작업을 수행할 수도 있습니다.x = new Array(3).join(".").split(".").map(...
빈 문자열 배열이 나타납니다.
꽤 추잡한 이야기지만, 적어도 그 문제와 의도는 꽤 명확하게 전달되었다.
왜가 문제이기 때문에, 이것은 JS가 설계된 방식과 관련이 있습니다.
이 동작을 설명하기 위해 생각할 수 있는 주된 이유는 두 가지가 있습니다.
: 소정의 ★★★★★★★★★★★★★★★★★★★」
x = 10000
★★★★★★★★★★★★★★★★★」new Array(x)
0 ~를 1000000으로 것이 .undefined
★★★★★★ 。되지 않음 "정의되지 않음": ""을 지정합니다.
a = [undefined, undefined]
★★★★★★★★★★★★★★★★★」b = new Array(2)
,a[1]
★★★★★★★★★★★★★★★★★」b[1]
다undefined
a[8]
★★★★★★★★★★★★★★★★★」b[8]
반환됩니다.undefined
범위를 벗어난다고 해도요
, 표기법, 표기법, 표기법, 표기법.empty x 3
는, 「 」의 이나 긴 입니다.undefined
「」의 값undefined
어쨌든 명시적으로 선언되지 않았기 때문입니다.
:된 어레이: " " " "a = [0]
★★★★★★★★★★★★★★★★★」a[9] = 9
,console.log(a)
(10) [0, empty x 8, 9]
명시적으로 선언된 두 값 간의 차이를 반환하여 공백을 자동으로 채웁니다.
회피책으로서 간단한 유틸리티 방법을 다음에 나타냅니다.
심플 맵 용도
function mapFor(toExclusive, callback) {
callback = callback || function(){};
var arr = [];
for (var i = 0; i < toExclusive; i++) {
arr.push(callback(i));
}
return arr;
};
var arr = mapFor(3, function(i){ return i; });
console.log(arr); // [0, 1, 2]
arr = mapFor(3);
console.log(arr); // [undefined, undefined, undefined]
완전한 예
다음은 옵션의 시작 인덱스를 지정할 수 있는 보다 완전한 예(온전성 검사 사용)입니다.
function mapFor() {
var from, toExclusive, callback;
if (arguments.length == 3) {
from = arguments[0];
toExclusive = arguments[1];
callback = arguments[2];
} else if (arguments.length == 2) {
if (typeof arguments[1] === 'function') {
from = 0;
toExclusive = arguments[0];
callback = arguments[1];
} else {
from = arguments[0];
toExclusive = arguments[1];
}
} else if (arguments.length == 1) {
from = 0;
toExclusive = arguments[0];
}
callback = callback || function () {};
var arr = [];
for (; from < toExclusive; from++) {
arr.push(callback(from));
}
return arr;
}
var arr = mapFor(1, 3, function (i) { return i; });
console.log(arr); // [1, 2]
arr = mapFor(1, 3);
console.log(arr); // [undefined, undefined]
arr = mapFor(3);
console.log(arr); // [undefined, undefined, undefined]
카운트다운
콜백에 전달된 인덱스를 조작하면 카운트를 거꾸로 할 수 있습니다.
var count = 3;
var arr = arrayUtil.mapFor(count, function (i) {
return count - 1 - i;
});
// arr = [2, 1, 0]
언급URL : https://stackoverflow.com/questions/5501581/javascript-new-arrayn-and-array-prototype-map-weirdness
'programing' 카테고리의 다른 글
MySQL을 datetime 필드와 비교()(시간이 아닌 날짜만) (0) | 2023.01.20 |
---|---|
$this->db->affected_rows()는 왜0을 반환합니까? (0) | 2023.01.20 |
Vuex 상태를 업데이트할 때 V-snackbar가 표시되지 않음 (0) | 2023.01.20 |
PHP 키워드 'var'의 역할은 무엇입니까? (0) | 2023.01.20 |
Java에서 두 세트를 비교하는 가장 빠른 방법은 무엇입니까? (0) | 2023.01.10 |