Warum funktioniert die „map“-Methode offenbar nicht bei Arrays, die über „new Array(count)“ erstellt wurden?
Lesezeit: 6 Minuten
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
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);
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å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
[…] 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.
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
14546400cookie-checkWarum funktioniert die „map“-Methode offenbar nicht bei Arrays, die über „new Array(count)“ erstellt wurden?yes
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