Die meisten Tutorials, die ich über Arrays in JavaScript gelesen habe (einschließlich w3schools und devguru ), schlagen vor, dass Sie ein Array mit einer bestimmten Länge initialisieren können, indem Sie dem Array-Konstruktor mithilfe der var test = new Array(4);
Syntax eine Ganzzahl übergeben .
Nachdem ich diese Syntax in meinen js-Dateien großzügig verwendet hatte, führte ich eine der Dateien über jsLint aus und es flippte aus:
Fehler: Problem in Zeile 1 Zeichen 22: Erwartet ')' und stattdessen '4' gesehen.
var test = neues Array (4);
Problem in Zeile 1, Zeichen 23: Erwartetes ';' und sah stattdessen ')'.
var test = neues Array (4);
Problem in Zeile 1, Zeichen 23: Erwartete eine Kennung und sah stattdessen ')'.
Nach dem Lesen der Erklärung des Verhaltens von jsLint sieht es so aus, als ob jsLint die new Array()
Syntax nicht wirklich mag und stattdessen []
beim Deklarieren von Arrays bevorzugt .
Ich habe also ein paar Fragen:
Erstens, warum? Gehe ich ein Risiko ein, wenn ich new Array()
stattdessen die Syntax verwende? Gibt es Browser-Inkompatibilitäten, die ich beachten sollte?
Und zweitens, wenn ich zur Syntax in eckigen Klammern wechsle, gibt es eine Möglichkeit, ein Array zu deklarieren und seine Länge in einer Zeile festzulegen, oder muss ich so etwas tun:
var test = [];
test.length = 4;
quelle
new Array()
im Allgemeinen ab, aber es ist in Ordnung, die Größe anzugeben. Ich denke, es kommt alles auf die Codekonsistenz im gesamten Kontext an.Antworten:
Warum möchten Sie die Länge initialisieren? Theoretisch besteht hierfür keine Notwendigkeit. Dies kann sogar zu verwirrendem Verhalten führen, da alle Tests,
length
bei denen ermittelt wird, ob ein Array leer ist oder nicht, melden, dass das Array nicht leer ist.Einige Tests zeigen , dass die anfängliche Länge von großen Arrays Einstellung kann effizienter sein , wenn das Array danach gefüllt, aber der Performance - Gewinn (falls vorhanden) scheint von Browser zu Browser unterscheiden.
jsLint gefällt nicht,
new Array()
weil der Konstruktor nicht eindeutig ist.erstellt ein leeres Array der Länge 4. Aber
Erstellt ein Array mit dem Wert
'4'
.Zu Ihrem Kommentar: In JS müssen Sie die Länge des Arrays nicht initialisieren. Es wächst dynamisch. Sie können die Länge einfach in einer Variablen speichern, z
quelle
for
führe ich eine Schleife aus, die über die Länge des Arrays iteriert und es füllt. Ich denke, es gibt andere Möglichkeiten, dies in JavaScript zu tun, also die eigentliche Antwort auf "Warum möchte ich das tun?" ist "Wegen alter Gewohnheiten, die sich beim Programmieren in anderen Sprachen gebildet haben." :)new Array(10)
kein Array mit 10 undefinierten Elementen erstellt wird. Es wird einfach ein leeres Array mit einer Länge von 10 erstellt. Siehe diese Antwort für die böse Wahrheit: stackoverflow.com/questions/18947892/…Array(5)
gibt Ihnen ein Array mit der Länge 5, aber ohne Werte, daher können Sie nicht darüber iterieren.Array.apply(null, Array(5)).map(function () {})
gibt Ihnen ein Array mit der Länge 5 und undefiniert als Werte, jetzt kann es wiederholt werden.Array.apply(null, Array(5)).map(function (x, i) { return i; })
gibt Ihnen ein Array mit der Länge 5 und den Werten 0,1,2,3,4.Array(5).forEach(alert)
tut nichts,Array.apply(null, Array(5)).forEach(alert)
gibt Ihnen 5 WarnungenES6
gibt unsArray.from
also jetzt kannst du auch nutzenArray.from(Array(5)).forEach(alert)
Wenn Sie mit einem bestimmten Wert initialisiert werden sollen, ist diese gut kennt ...
Array.from('abcde')
,Array.from('x'.repeat(5))
oder
Array.from({length: 5}, (v, i) => i) // gives [0, 1, 2, 3, 4]
quelle
Array
mehrere Argumente angegeben werden, wird dasarguments
Objekt durchlaufen und jeder Wert wird explizit auf das neue Array angewendet . Wenn SieArray.apply
mit einem Array oder einem Objekt mit einer Längeneigenschaft aufrufen,Array
wird die Länge verwendet, um jeden Wert des neuen Arrays explizit festzulegen. Dies ist der Grund, warumArray(5)
es ein Array von 5 ElisionenArray.apply(null, Array(5))
gibt , während es ein Array von 5 undefinierten gibt. Weitere Informationen finden Sie in dieser Antwort.Array.apply(null, Array(5))
kann auch geschrieben werden alsArray.apply(null, {length: 5})
. Es gibt wirklich keinen großen Unterschied, aber letzteres ist eindeutig klar, dass die Absicht darin besteht, ein Array vonlength 5
und nicht ein Array zu erstellen , das5
Mit ES2015 können
.fill()
Sie jetzt einfach Folgendes tun:Welches ist viel prägnanter als
Array.apply(0, new Array(n)).map(i => value)
Es ist möglich, das
0
In zu löschen.fill()
und ohne Argumente auszuführen, wodurch das Array gefüllt wirdundefined
. ( Dies schlägt jedoch in Typescript fehl. )quelle
When Array is called as a function rather than as a constructor, it also creates and initializes a new Array object. Thus the function call Array(…) is equivalent to the object creation expression new Array(…) with the same arguments
Array(n).fill()
ODER
Hinweis: Sie können keine leeren Slots schleifen, z
Array(4).forEach(() => …)
ODER
( Typoskript sicher )
ODER
Klassische Methode mit einer Funktion (funktioniert in jedem Browser)
Verschachtelte Arrays erstellen
Beim Erstellen eines 2D- Arrays mit dem
fill
sollte intuitiv neue Instanzen erstellt werden. Was aber tatsächlich passieren wird, ist, dass dasselbe Array als Referenz gespeichert wird.Lösung
Ein 3x2-Array sieht also ungefähr so aus:
N-dimensionales Array
Initialisiere ein Schachbrett
quelle
a[0].push(9);
// [ [6, 9], [6], [6] ]
sollte sein,a[0].push(9);
// [ [6, 9], [6, 9], [6, 9] ]
weil jedes verschachtelte Array als Referenz gespeichert ist, so dass das Mutieren eines Arrays den Rest beeinflusst. Sie haben es vielleicht gerade falsch geschrieben, obwohl ich denke :)Der kürzeste:
quelle
[
ohne a zu verwenden,;
da dies versucht, die obige Zeile zu dereferenzieren. Ein sicherer Weg, diese Zeile vorhersehbar in einem beliebigen Teil des Codes zu verwenden, wäre:;[...Array(1000)]//.whateverOpsNeeded()
[...Array(5)].map((item, index) => ({ index }))
Versuchen Sie dies auch:[...Array(5)]; console.log('hello');
const a = 'a'
und die nächste Zeile ist[...Array(5)].//irrelevent
. Was würde die erste Zeile Ihrer Meinung nach bewirken?const a = 'a'[...Array(5)]
Dies würde zu Folgendem führen:Uncaught SyntaxError: Unexpected token ...
const a = 'a'
wird in diesem Fall ein Lint-Fehler sein. Jedenfalls hat es wirklich nichts mit dieser Antwort zu tun.ES6 führt ein, mit
Array.from
dem SieArray
aus beliebigen "Array-ähnlichen" oder iterierbaren Objekten ein Objekt erstellen können:In diesem Fall handelt es sich
{length: 10}
um die minimale Definition eines "Array-ähnlichen" Objekts: ein leeres Objekt mit nur einerlength
definierten Eigenschaft.Array.from
Ermöglicht die Zuordnung eines zweiten Arguments zum resultierenden Array.quelle
Dadurch wird die Eigenschaft length auf 4 initialisiert:
quelle
var size = 42; var myArray = eval("["+",".repeat(size)+"]");
? (Nicht so ernst;)Ich bin überrascht, dass keine funktionale Lösung vorgeschlagen wurde, mit der Sie die Länge in einer Zeile festlegen können. Folgendes basiert auf UnderscoreJS:
Aus den oben genannten Gründen würde ich dies vermeiden, es sei denn, ich wollte das Array mit einem bestimmten Wert initialisieren. Es ist interessant festzustellen, dass es andere Bibliotheken gibt, die einen Bereich implementieren, einschließlich Lo-Dash und Lazy, die möglicherweise unterschiedliche Leistungsmerkmale aufweisen.
quelle
Bitte, die Leute geben ihre alten Gewohnheiten noch nicht auf. Es gibt einen großen Geschwindigkeitsunterschied zwischen der einmaligen Zuweisung von Speicher und der Arbeit mit den Einträgen in diesem Array (wie bisher) und der mehrmaligen Zuweisung, wenn ein Array wächst (was das System zwangsläufig unter der Haube mit anderen vorgeschlagenen Methoden tut). .
Nichts davon ist natürlich wichtig, bis Sie mit größeren Arrays etwas Cooles machen möchten. Dann tut es.
Da es in JS derzeit noch keine Option zum Festlegen der Anfangskapazität eines Arrays zu geben scheint, verwende ich Folgendes ...
Es gibt Kompromisse:
standard
Array reserviert permanent so viel Speicherplatz wie das größte Array, nach dem Sie gefragt haben.Aber wenn es zu dem passt, was Sie tun, kann es eine Auszahlung geben. Informelles Timing setzt
bei ziemlich hoher Geschwindigkeit (ungefähr 50 ms für die 10000, da es mit n = 1000000 ungefähr 5 Sekunden dauerte) und
bei weit über einer Minute (ungefähr 90 Sekunden für den 10000 auf derselben Chromkonsole oder ungefähr 2000 Mal langsamer). Das ist nicht nur die Zuordnung, sondern auch die 10000 Pushs, for-Schleife usw.
quelle
(Dies war wahrscheinlich besser als Kommentar, wurde aber zu lang)
Nachdem ich dies gelesen hatte, war ich neugierig, ob die Vorzuweisung tatsächlich schneller war, weil es theoretisch so sein sollte. Dieser Blog gab jedoch einige Tipps, die davon abraten . Http://www.html5rocks.com/en/tutorials/speed/v8/ .
Da ich immer noch unsicher bin, habe ich es auf die Probe gestellt. Und wie sich herausstellt, scheint es tatsächlich langsamer zu sein.
Dieser Code liefert nach einigen gelegentlichen Läufen Folgendes:
quelle
quelle
[5: 0]
dies ein spärliches Array ist und wahrscheinlich nicht das, was gewünscht wird.Hier ist eine andere Lösung
Das erste Argument von
apply()
ist eine Objektbindung, die uns hier nicht wichtig ist, also setzen wir sie aufnull
.Array.apply(..)
ruft dieArray(..)
Funktion auf und verteilt den{ length: 3 }
Objektwert als Argumente.quelle
new Array(n)
ein Array wie dieses nicht initialisierennew Array(n).map(function(notUsed,index){...})
, aber mit diesem Ansatz können Sie es, wie @zangw erwähnt, tun. +1 von mir.Der Array-Konstruktor hat eine mehrdeutige Syntax , und JSLint verletzt schließlich nur Ihre Gefühle.
Wenn Ihr Beispielcode fehlerhaft ist, löst die zweite
var
Anweisung a ausSyntaxError
. Sie legen die Eigenschaftlength
des Arrays festtest
, sodass keine weitere erforderlich istvar
.Was Ihre Optionen angeht,
array.length
ist dies die einzige "saubere". Die Frage ist, warum müssen Sie die Größe überhaupt einstellen? Versuchen Sie, Ihren Code umzugestalten, um diese Abhängigkeit zu beseitigen.quelle
var test
. Das war ein schlampiges Kopieren und Einfügen von meiner Seite.Angenommen, die Länge des Arrays ist konstant. In Javascript tun wir Folgendes:
const intialArray = new Array(specify the value);
quelle
Wie oben erläutert, ist die Verwendung
new Array(size)
etwas gefährlich. Platzieren Sie es nicht direkt, sondern in einer "Array Creator-Funktion". Sie können leicht sicherstellen, dass diese Funktion fehlerfrei ist und Sie vermeiden die Gefahr einesnew Array(size)
direkten Anrufs . Sie können ihm auch einen optionalen Standardanfangswert geben. DiesecreateArray
Funktion macht genau das:quelle
In den meisten Antworten wird es
fill
dem Array empfohlen, da sonst "Sie nicht darüber iterieren können" , aber dies ist nicht wahr. Sie können ein leeres Array iterieren, nur nicht mitforEach
. Während Schleifen, für Schleifen und für i Schleifen funktionieren gut.Funktioniert nicht.
Diese Arbeit:
Überprüfen Sie diese Geige anhand der obigen Beispiele.
Auch Winkel
*ngFor
funktionieren gut mit einem leeren Array:quelle
Sie können die Array-Länge mithilfe von festlegen
array.length = youValue
So wäre es
quelle
Der Grund, den Sie nicht verwenden sollten,
new Array
wird durch diesen Code demonstriert:Ein anderer Code könnte mit der Array-Variablen in Konflikt geraten. Ich weiß, es ist ein bisschen weit hergeholt, dass irgendjemand solchen Code schreiben würde, aber trotzdem ...
Wie Felix King sagte, ist die Benutzeroberfläche etwas inkonsistent und kann zu einigen sehr schwer auffindbaren Fehlern führen.
Wenn Sie ein Array mit der Länge = x
new Array(x)
möchten , das mit undefiniert gefüllt ist (wie dies der Fall wäre), können Sie Folgendes tun:quelle
alert
undundefined
, weil ein anderer Code könnte Chaos mit ihnen. Das zweite Beispiel ist weniger lesbar alsnew Array(4)
und liefert nicht das gleiche Ergebnis: jsfiddle.net/73fKd