Warum funktioniert die „map“-Methode offenbar nicht bei Arrays, die über „new Array(count)“ erstellt wurden?

Lesezeit: 6 Minuten

Benutzeravatar von Rampion
Rampion

Ich habe dies in Firefox-3.5.7/Firebug-1.5.3 und Firefox-3.6.16/Firebug-1.6.2 beobachtet

Wenn ich Firebug starte:

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]

Was ist denn hier los? Ist das ein Fehler oder verstehe ich die Verwendung falsch? new Array(3)?

  • Ich erhalte nicht die gleichen Ergebnisse, die Sie mit der Array-Literal-Notation sehen. Ich erhalte immer noch undefiniert statt 0. Das Ergebnis 0 erhalte ich nur, wenn ich so etwas setze var y = x.map(function(){return 0; });, und ich erhalte dies sowohl für die neue Array()-Methode als auch für das Array-Literal. Ich habe es in Firefox 4 und Chrome getestet.

    – RussellUresti

    31. März 2011 um 14:50 Uhr


  • Auch in Chrome kaputt, das könnte in der Sprache definiert sein, obwohl es keinen Sinn ergibt, also hoffe ich wirklich, dass es das nicht ist

    – Hashbrown

    29. Januar 2020 um 0:37

  • Wenn Sie „new Array(4)“ verwenden, ist das Ergebnis kein Array mit 4 „undefiniert“. Sie erhalten ein anderes Ergebnis – Sie erhalten „(4)“ [empty × 4]”

    – Yehonatan Yehezkel

    31. Mai 2022 um 8:58

cstuncsiks Benutzeravatar
cstuncsik

Ich hatte eine Aufgabe, bei der ich nur die Länge des Arrays kannte und die Elemente transformieren musste. Ich wollte so etwas machen:

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

So erstellen Sie schnell ein Array wie dieses:

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

Aber es hat nicht funktioniert, weil: (siehe Jonathan Lonowskis Antwort)

Die Lösung könnte darin bestehen, die Array-Elemente mithilfe von mit einem beliebigen Wert (auch mit einem undefinierten Wert) zu füllen Array.prototype.fill()

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

console.log(new Array(10).fill(undefined).map((val, idx) => idx));

Aktualisieren

Eine andere Lösung könnte sein:

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

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

  • Beachten Sie, dass Sie das nicht angeben müssen undefined im .fill() Methode, die den Code sehr leicht vereinfacht let arr = new Array(10).fill().map((val,idx) => idx);

    – Yann Eves

    11. Februar 2016 um 10:39


  • Ebenso können Sie verwenden Array.from(Array(10))

    Benutzer10275798

    15. Juli 2019 um 7:47 Uhr

  • Ich würde die Antwort von @eden-landau empfehlen, da es eine sauberere Möglichkeit ist, ein Array zu initialisieren

    – Sebastien H.

    6. August 2021 um 14:41 Uhr

  • Die Antwort ist falsch

    – Piliponful

    22. Februar 2022 um 11:57 Uhr

  • Denken Sie daran, bei der Zuordnung zu einem Objekt die Rückgabetaste zu verwenden. :X Array.apply(null, Array(10)).map(() => { return {}; });

    – Trevor Karjanis

    19. Mai 2022 um 19:18 Uhr


David Mårtenssons Benutzeravatar
David Mårtensson

Es scheint, dass das erste Beispiel

x = new Array(3);

Erstellt ein Array mit einer Länge von 3, jedoch ohne Elemente, also die Indizes [0], [1] Und [2] wird nicht erstellt.

Und der zweite erstellt ein Array mit den drei undefinierten Objekten. In diesem Fall werden die Indizes/Eigenschaften selbst erstellt, aber die Objekte, auf die sie verweisen, sind undefiniert.

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

Da die Karte auf der Liste der Indizes/Eigenschaften und nicht auf der festgelegten Länge ausgeführt wird, wird sie nicht ausgeführt, wenn keine Indizes/Eigenschaften erstellt werden.

  • Aus MDC (Hervorhebung von mir): „map ruft eine bereitgestellte Rückruffunktion einmal für jedes Element in einem Array der Reihe nach auf und erstellt aus den Ergebnissen ein neues Array. callback wird nur für Indizes des Arrays aufgerufen, denen Werte zugewiesen wurden; Es wird nicht für Indizes aufgerufen, die gelöscht wurden oder denen nie Werte zugewiesen wurden. xDen Werten wurden keine explizit Werte zugewiesen, wohingegen y‘s wurden zugewiesen, auch wenn es der Wert war undefined.

    – Martijn

    31. März 2011 um 15:03


  • Liegt es also an einem JavaScript-Fehler, bei dem nicht überprüft werden kann, ob es sich um einen undefinierten Zeiger oder einen Zeiger auf undefiniert handelt? Ich meine (new Array(1))[0] === [undefined][0].

    – Trevor Norris

    7. September 2012 um 22:20 Uhr

  • Nun, ein Array undefinierter Objekte unterscheidet sich von einem Array von Zeigern auf undefinierte Objekte. Ein Array von Undefinierten wäre wie ein Array von Nullwerten, [null, null, null] während ein Array von Zeigern auf undefiniert wäre [343423, 343424, 343425] zeigt auf null und null und null. Die zweiten Lösungen verfügen über echte Zeiger, die auf Speicheradressen zeigen, während die ersten Lösungen nirgendwo zeigen. Ob das ein Versagen von JS ist, ist wahrscheinlich Gegenstand einer Diskussion, aber nicht hier 😉

    – David Mårtensson

    17. September 2012 um 16:10 Uhr

  • @TrevNorris, das kannst du ganz einfach testen hasOwnProperty es sei denn hasOwnProperty selbst hat einen Fehler: (new Array(1)).hasOwnProperty(0) === false Und [undefined].hasOwnProperty(0) === true. Tatsächlich können Sie mit genau das Gleiche tun in: 0 in [undefined] === true Und 0 in new Array(0) === false.

    – Tintenfisch314

    19. März 2015 um 20:46

  • Die Rede von „undefinierten Zeigern“ in JavaScript verwirrt das Problem. Der gesuchte Begriff ist „Elision“. x = new Array(3); ist äquivalent zu x = [,,,];nicht x = [undefined, undefined, undefined].

    – Matt Kantor

    14. April 2015 um 2:53

Mit ES6 ist das möglich [...Array(10)].map((a, b) => a) schnell und einfach!

  • Vor ES6 können Sie verwenden new Array(10).fill(). Gleiches Ergebnis wie [...Array(10)]

    – Molomby

    1. August 2017 um 2:02


  • Bei großen Arrays führt die Spread-Syntax zu Problemen, daher ist es besser, sie zu vermeiden

    Benutzer10275798

    15. Juli 2019 um 7:42 Uhr

  • oder [...Array(10).keys()]

    – Chungzuwalla

    19. Mai 2020 um 10:06 Uhr

  • Ich weiß, wie es funktioniert, aber bitte hinzufügen eine Erklärungfür diejenigen, die es nicht tun

    – vsync

    27. Okt. 2020 um 18:38 Uhr


ES6-Lösung:

[...Array(10)]

Funktioniert jedoch nicht mit Typoskript (2.3).

Von der MDC-Seite für map:

[…] callback wird nur für Indizes des Arrays aufgerufen, denen ein Wert zugewiesen wurde; […]

[undefined] Wendet den Setter tatsächlich auf die Indizes an, sodass map wird iterieren, wohingegen new Array(1) initialisiert lediglich den/die Index(e) mit einem Standardwert von undefined So map überspringt es.

Ich glaube, das ist für alle gleich Iterationsmethoden.

Die Arrays sind unterschiedlich. Der Unterschied besteht darin new Array(3) erstellt ein Array mit einer Länge von drei, aber ohne Eigenschaften, while [undefined, undefined, undefined] Erstellt ein Array mit einer Länge von drei und drei Eigenschaften namens „0“, „1“ und „2“, jeweils mit einem Wert von undefined. Sie können den Unterschied anhand der erkennen in Operator:

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

Dies liegt an der etwas verwirrenden Tatsache, dass, wenn Sie versuchen, den Wert einer nicht vorhandenen Eigenschaft eines nativen Objekts in JavaScript abzurufen, dieser zurückgegeben wird undefined (anstatt einen Fehler auszulösen, wie es der Fall ist, wenn Sie versuchen, auf eine nicht vorhandene Variable zu verweisen), was dasselbe ist, was Sie erhalten, wenn die Eigenschaft zuvor explizit auf festgelegt wurde undefined.

Aus Gründen, die in anderen Antworten ausführlich erläutert wurden, Array(n).map funktioniert nicht. Allerdings in ES2015 Array.from akzeptiert eine Kartenfunktion:

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

  • Das ist für mich die sauberste Antwort.

    – Sebastien H.

    6. August 2021 um 14:42 Uhr

1454640cookie-checkWarum funktioniert die „map“-Methode offenbar nicht bei Arrays, die über „new Array(count)“ erstellt wurden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy