programing

JavaScript "new Array(n)" 및 "Array.protype.map" 이상

newsource 2023. 1. 20. 16:11

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) 「」로undefinedmap너뜁니니다다

나는 이것이 모든 반복 방법에서 같다고 믿는다.

어레이가 다르다. 점은 '하다'는 것입니다.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]undefineda[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