2015-02-06 8 views
24

Nach den MDN documentation for new Array(length) kann ich ein Array mit einer bestimmten Länge als solche initialisieren:Ist ein neues JavaScript-Array mit der Länge unbrauchbar?

var a = new Array(10); 
a.length; // => 10 
a; // => [undefined x 10] 

jedoch anscheinend kann ich nicht Methoden wie map(...) auf das neue Array, auch wenn auf andere Weise konstruiert Arrays arbeitet fein:

a.map(function() { return Math.random(); }); 
// => [undefined x 10] -- wtf? 
[undefined, undefined].map(function() { return Math.random(); }); 
// => [0.07192076672799885, 0.8052175589837134] 

Warum ist das der Fall?

Ich verstehe, aus dieser Erfahrung (und das Suchen im Internet), dass der Array-Konstruktor mit Länge ein schwarzes Loch von unerklärlichem Verhalten ist, aber nicht die ECMA   262-Spezifikation bietet eine Erklärung?

+3

Ich vermute, dass '[undefined x 10]' ist nur eine Darstellung in Ihrer Konsole, dass Sie sagt habe ein leeres 10-dimensionales Array. In Firefox heißt es nur 'Array [<10 leere Slots>]'. – mc10

+2

FWIW '[undefiniert, undefiniert] .map (function() {return Math.random();});' führt keine Operationen mit den undefinierten Elementen aus, weshalb diese Gleitkommazahlen zurückgegeben werden. [Wenn Sie sie als Parameter an den Callback übergeben und versucht haben, ihn zu verwenden, würde 'map' fehlschlagen.] (Http://jsfiddle.net/bdwm4714/). [Die map-Spezifikation sagt] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) "Es wird nicht für Indizes aufgerufen, die undefiniert sind gelöscht wurden oder denen noch nie Werte zugewiesen wurden. " – Andy

+0

@Andy: Ich weiß nicht, dieses Snippet verhält sich wie erwartet -> '[undefined] .map (Funktion (x) {zurück" OK: "+ x;}) // => [" OK: undefined "]'. Vielleicht ist das der Unterschied zwischen "undefinierten Werten" und "[Indizes], denen nie Werte zugewiesen wurden. – maerics

Antwort

19

new Array(10) gibt kein Array zurück, das mit 10 undefined s gefüllt ist. Stattdessen wird ein Array ohne Elemente und mit einer length Eigenschaft von 10 zurückgegeben.

Siehe den Unterschied:

var arr1 = new Array(1), 
    arr2 = [undefined]; 
arr1.length === arr2.length; // Both are `1` 
arr1[0] === arr2[1];   // Both are `undefined` 
arr1.hasOwnProperty(0);  // false 
arr2.hasOwnProperty(0);  // true 

Daher ECMAScript   5-Array Methoden diese nicht vorhandenen Eigenschaften überspringen. Insbesondere, wenn sie von 0 bis length iterieren, überprüfen sie die interne Methode des Arrays .

Sie können das Problem beheben leicht mit ECMAScript (die polyfilled sein kann):

new Array(10).fill().map(Math.random); 
+2

War das gleiche sagen, aber Sie haben mich dazu geschlagen. – Travis

+1

Schön, aber was ist der Punkt, um ein Array mit einer Länge von 10 w/o Elemente zu instanziieren? Es gibt einen nützlichen Fall dafür? – DontVoteMeDown

+3

10 @DontVoteMeDown Wenn Sie ein riesiges Array erstellen und dem Browser mitteilen wollen, wie viele Elemente es haben soll, kann der Browser den Speicherplatz im Speicher reservieren. Die Größe beim Einfügen jedes Elements kann langsamer sein. – Oriol

Verwandte Themen