Ein Array ist eine Abbildung von Indizes (natürliche Zahlen, beginnend bei Null) auf beliebige Werte. Die Werte (der Wertebereich der Abbildung) werden als Elemente des Arrays bezeichnet. Die bequemste Art, ein Array zu erstellen, ist über ein Array-Literal. Ein solches Literal zählt die Array-Elemente auf; die Position eines Elements legt implizit seinen Index fest.
In diesem Kapitel werde ich zuerst die grundlegenden Array-Mechanismen wie indizierten Zugriff und die length-Eigenschaft behandeln, und dann die Array-Methoden durchgehen.
Dieser Abschnitt bietet einen schnellen Überblick über Arrays. Details werden später erklärt.
Als erstes Beispiel erstellen wir ein Array arr über ein Array-Literal (siehe Erstellen von Arrays) und greifen auf Elemente zu (siehe Array-Indizes)
> var arr = [ 'a', 'b', 'c' ]; // array literal > arr[0] // get element 0 'a' > arr[0] = 'x'; // set element 0 > arr [ 'x', 'b', 'c' ]
Wir können die Array-Eigenschaft length (siehe length) verwenden, um Elemente zu entfernen und anzuhängen:
> var arr = [ 'a', 'b', 'c' ]; > arr.length 3 > arr.length = 2; // remove an element > arr [ 'a', 'b' ] > arr[arr.length] = 'd'; // append an element > arr [ 'a', 'b', 'd' ]
Die Array-Methode push() bietet eine weitere Möglichkeit, ein Element anzuhängen.
> var arr = [ 'a', 'b' ];
> arr.push('d')
3
> arr
[ 'a', 'b', 'd' ]Der ECMAScript-Standard definiert Arrays als Abbildungen (Dictionaries) von Indizes auf Werte. Mit anderen Worten, Arrays müssen nicht zusammenhängend sein und können Löcher aufweisen. Zum Beispiel:
> var arr = []; > arr[0] = 'a'; 'a' > arr[2] = 'b'; 'b' > arr [ 'a', , 'b' ]
Das vorherige Array hat ein Loch: Es gibt kein Element am Index 1. Löcher in Arrays erklärt Löcher im Detail.
Beachten Sie, dass die meisten JavaScript-Engines Arrays ohne Löcher intern optimieren und sie zusammenhängend speichern.
Arrays sind immer noch Objekte und können Objekteigenschaften haben. Diese werden nicht als Teil des eigentlichen Arrays betrachtet; das heißt, sie werden nicht als Array-Elemente betrachtet:
> var arr = [ 'a', 'b' ]; > arr.foo = 123; > arr [ 'a', 'b' ] > arr.foo 123
Sie erstellen ein Array über ein Array-Literal.
varmyArray=['a','b','c'];
Nachgestellte Kommas in Arrays werden ignoriert.
> [ 'a', 'b' ].length 2 > [ 'a', 'b', ].length 2 > [ 'a', 'b', ,].length // hole + trailing comma 3
Es gibt zwei Möglichkeiten, den Konstruktor Array zu verwenden: Sie können ein leeres Array mit einer gegebenen Länge oder ein Array erstellen, dessen Elemente die gegebenen Werte sind. Für diesen Konstruktor ist new optional: Wenn Sie ihn als normale Funktion aufrufen (ohne new), tut er dasselbe, als wenn Sie ihn als Konstruktor aufrufen.
> var arr = new Array(2); > arr.length 2 > arr // two holes plus trailing comma (ignored!) [ , ,]
Einige Engines weisen möglicherweise zusammenhängenden Speicher vor, wenn Sie Array() auf diese Weise aufrufen, was die Leistung geringfügig verbessern kann. Stellen Sie jedoch sicher, dass die erhöhte Ausführlichkeit und Redundanz es wert ist!
Diese Art des Aufrufs von Array ist ähnlich wie ein Array-Literal:
// The same as ['a', 'b', 'c']:vararr1=newArray('a','b','c');
Das Problem ist, dass Sie keine Arrays mit einer einzelnen Zahl darin erstellen können, da dies als Erstellung eines Arrays interpretiert wird, dessen length die Zahl ist.
> new Array(2) // alas, not [ 2 ]
[ , ,]
> new Array(5.7) // alas, not [ 5.7 ]
RangeError: Invalid array length
> new Array('abc') // ok
[ 'abc' ]Wenn Sie mehrere Dimensionen für Elemente benötigen, müssen Sie Arrays verschachteln. Wenn Sie solche verschachtelten Arrays erstellen, können die innersten Arrays nach Bedarf wachsen. Wenn Sie jedoch direkten Zugriff auf Elemente wünschen, müssen Sie mindestens die äußeren Arrays erstellen. Im folgenden Beispiel erstelle ich eine Drei-mal-Drei-Matrix für Tic-tac-toe. Die Matrix ist vollständig mit Daten gefüllt (im Gegensatz zum Wachsenlassen von Zeilen nach Bedarf):
// Create the Tic-tac-toe boardvarrows=[];for(varrowCount=0;rowCount<3;rowCount++){rows[rowCount]=[];for(varcolCount=0;colCount<3;colCount++){rows[rowCount][colCount]='.';}}// Set an X in the upper right cornerrows[0][2]='X';// [row][column]// Print the boardrows.forEach(function(row){console.log(row.join(' '));});
Hier ist die Ausgabe.
. . X . . . . . .
Ich wollte, dass das Beispiel den allgemeinen Fall demonstriert. Offensichtlich können Sie, wenn eine Matrix so klein und mit festen Dimensionen ist, sie über ein Array-Literal einrichten.
varrows=[['.','.','.'],['.','.','.'],['.','.','.']];
Wenn Sie mit Array-Indizes arbeiten, müssen Sie die folgenden Grenzen beachten:
Indizes außerhalb des Bereichs werden als normale Eigenschaftsschlüssel (Zeichenketten!) behandelt. Sie erscheinen nicht als Array-Elemente und beeinflussen die length-Eigenschaft nicht. Zum Beispiel:
> var arr = []; > arr[-1] = 'a'; > arr [] > arr['-1'] 'a' > arr[4294967296] = 'b'; > arr [] > arr['4294967296'] 'b'
Der in-Operator erkennt, ob ein Objekt eine Eigenschaft mit einem gegebenen Schlüssel hat. Er kann aber auch verwendet werden, um festzustellen, ob ein gegebener Elementindex in einem Array existiert. Zum Beispiel:
> var arr = [ 'a', , 'b' ]; > 0 in arr true > 1 in arr false > 10 in arr false
Zusätzlich zum Löschen von Eigenschaften löscht der delete-Operator auch Array-Elemente. Das Löschen von Elementen erzeugt Löcher (die length-Eigenschaft wird nicht aktualisiert):
> var arr = [ 'a', 'b' ]; > arr.length 2 > delete arr[1] // does not update length true > arr [ 'a', ] > arr.length 2
Sie können auch nachgestellte Array-Elemente löschen, indem Sie die Länge eines Arrays verringern (siehe length für Details). Um Elemente zu entfernen, ohne Löcher zu erzeugen (d. h. die Indizes nachfolgender Elemente werden dekrementiert), verwenden Sie Array.prototype.splice() (siehe Hinzufügen und Entfernen von Elementen (destruktiv)). In diesem Beispiel entfernen wir zwei Elemente am Index 1.
> var arr = ['a', 'b', 'c', 'd']; > arr.splice(1, 2) // returns what has been removed [ 'b', 'c' ] > arr [ 'a', 'd' ]
Dies ist ein fortgeschrittener Abschnitt. Normalerweise müssen Sie die hier erklärten Details nicht kennen.
Array-Indizes sind nicht das, was sie scheinen. Bisher habe ich so getan, als wären Array-Indizes Zahlen. Und so implementieren JavaScript-Engines Arrays intern. Die ECMAScript-Spezifikation sieht Indizes jedoch anders. Paraphrasierung von Abschnitt 15.4
P (eine Zeichenkette) ist einArray-Index, wenn und nur wenn ToString(ToUint32(P)) gleich P ist und ToUint32(P) nicht gleich 232−1 ist. Was das bedeutet, wird gleich erklärt.Mit anderen Worten, in der Welt der Spezifikation werden alle Werte in Klammern in Zeichenketten umgewandelt und als Eigenschaftsschlüssel interpretiert, selbst Zahlen. Die folgende Interaktion zeigt dies:
> var arr = ['a', 'b']; > arr['0'] 'a' > arr[0] 'a'
Um ein Array-Index zu sein, muss ein Eigenschaftsschlüssel P (eine Zeichenkette!) gleich dem Ergebnis der folgenden Berechnung sein:
P in eine Zahl um.Das bedeutet, dass ein Array-Index eine stringifizierte Ganzzahl i im 32-Bit-Bereich 0 ≤ i < 232−1 sein muss. Die Obergrenze wurde in der Spezifikation explizit ausgeschlossen (wie zuvor zitiert). Sie ist für die maximale Länge reserviert. Um zu sehen, wie diese Definition funktioniert, verwenden wir dieFunktion ToUint32() aus 32-Bit-Ganzzahlen über bitweise Operatoren.
Erstens wird eine Zeichenkette, die keine Zahl enthält, immer in 0 umgewandelt, was nach der Stringifizierung nicht mit der Zeichenkette übereinstimmt.
> ToUint32('xyz')
0
> ToUint32('?@#!')
0Zweitens wird eine stringifizierte Ganzzahl außerhalb des Bereichs ebenfalls in eine völlig andere Ganzzahl umgewandelt, die nach der Stringifizierung nicht mit der Zeichenkette übereinstimmt.
> ToUint32('-1')
4294967295
> Math.pow(2, 32)
4294967296
> ToUint32('4294967296')
0Drittens werden stringifizierte Nicht-Ganzzahlen in Ganzzahlen umgewandelt, die wiederum unterschiedlich sind.
> ToUint32('1.371')
1Beachten Sie, dass die Spezifikation auch sicherstellt, dass Array-Indizes keine Exponenten haben.
> ToUint32('1e3')
1000Und dass sie keine führenden Nullen haben.
> var arr = ['a', 'b']; > arr['0'] // array index 'a' > arr['00'] // normal property undefined
Die grundlegende Funktion der length-Eigenschaft besteht darin, den höchsten Index in einem Array zu verfolgen:
> [ 'a', 'b' ].length 2 > [ 'a', , 'b' ].length 3
Somit zählt length nicht die Anzahl der Elemente, sodass Sie Ihre eigene Funktion dafür schreiben müssten. Zum Beispiel:
functioncountElements(arr){varelemCount=0;arr.forEach(function(){elemCount++;});returnelemCount;}
Um Elemente (nicht-Löcher) zu zählen, haben wir die Tatsache genutzt, dass forEach Löcher überspringt. Hier ist die Interaktion:
> countElements([ 'a', 'b' ]) 2 > countElements([ 'a', , 'b' ]) 2
Das manuelle Erhöhen der Länge eines Arrays hat bemerkenswert wenig Auswirkungen auf ein Array; es erzeugt nur Löcher:
> var arr = [ 'a', 'b' ]; > arr.length = 3; > arr // one hole at the end [ 'a', 'b', ,]
Das letzte Ergebnis hat zwei Kommas am Ende, da ein nachgestelltes Komma optional ist und daher immer ignoriert wird.
Was wir gerade getan haben, hat keine Elemente hinzugefügt.
> countElements(arr) 2
Die length-Eigenschaft fungiert jedoch als Zeiger, der angibt, wo neue Elemente eingefügt werden sollen. Zum Beispiel:
> arr.push('c')
4
> arr
[ 'a', 'b', , 'c' ]Somit erstellt das Setzen der Anfangslänge eines Arrays über den Array-Konstruktor ein Array, das vollständig leer ist.
> var arr = new Array(2); > arr.length 2 > countElements(arr) 0
Wenn Sie die Länge eines Arrays verringern, werden alle Elemente an der neuen Länge und darüber hinaus gelöscht:
> var arr = [ 'a', 'b', 'c' ]; > 1 in arr true > arr[1] 'b' > arr.length = 1; > arr [ 'a' ] > 1 in arr false > arr[1] undefined
Wenn Sie die Länge eines Arrays auf 0 setzen, wird es leer. Dies ermöglicht es Ihnen, ein Array für jemand anderen zu leeren. Zum Beispiel:
functionclearArray(arr){arr.length=0;}
Hier ist die Interaktion
> var arr = [ 'a', 'b', 'c' ]; > clearArray(arr) > arr []
Beachten Sie jedoch, dass dieser Ansatz langsam sein kann, da jedes Array-Element explizit gelöscht wird. Ironischerweise ist das Erstellen eines neuen leeren Arrays oft schneller.
arr=[];
Sie müssen sich der Tatsache bewusst sein, dass das Setzen der Länge eines Arrays auf Null alle betrifft, die das Array gemeinsam nutzen:
>vara1=[1,2,3];>vara2=a1;>a1.length=0;>a1[]>a2[]
Im Gegensatz dazu ändert die Zuweisung eines leeren Arrays nichts.
>vara1=[1,2,3];>vara2=a1;>a1=[];>a1[]>a2[1,2,3]
Die maximale Array-Länge beträgt 232−1:
> var arr1 = new Array(Math.pow(2, 32)); // not ok
RangeError: Invalid array length
> var arr2 = new Array(Math.pow(2, 32)-1); // ok
> arr2.push('x');
RangeError: Invalid array lengthArrays sind Abbildungen von Indizes auf Werte. Das bedeutet, dass ArraysLöcher haben können, Indizes kleiner als die Länge, die im Array fehlen. Das Lesen eines Elements an einem dieser Indizes gibt undefined zurück.
Es wird empfohlen, Löcher in Arrays zu vermeiden. JavaScript behandelt sie inkonsistent (d. h. einige Methoden ignorieren sie, andere nicht). Glücklicherweise müssen Sie normalerweise nicht wissen, wie Löcher behandelt werden: Sie sind selten nützlich und beeinträchtigen die Leistung negativ.
Sie können Löcher erstellen, indem Sie Array-Indizes zuweisen:
> var arr = []; > arr[0] = 'a'; > arr[2] = 'c'; > 1 in arr // hole at index 1 false
Sie können auch Löcher erstellen, indem Sie Werte in Array-Literalen weglassen.
> var arr = ['a',,'c']; > 1 in arr // hole at index 1 false
Sie benötigen zwei nachgestellte Kommas, um ein nachgestelltes Loch zu erstellen, da das letzte Komma immer ignoriert wird.
> [ 'a', ].length 1 > [ 'a', ,].length 2
Dieser Abschnitt untersucht die Unterschiede zwischen einem Loch und undefined als Element. Da das Lesen eines Lochs undefined zurückgibt, sind beide sehr ähnlich.
Ein Array mit Löchern wird alssparsch bezeichnet. Ein Array ohne Löcher wird alsdicht bezeichnet. Dichte Arrays sind zusammenhängend und haben ein Element an jedem Index - beginnend bei Null und endend bei length − 1. Vergleichen wir die folgenden beiden Arrays, ein sparsames und ein dichtes Array. Die beiden sind sehr ähnlich:
varsparse=[,,'c'];vardense=[undefined,undefined,'c'];
Ein Loch ist fast so, als hätte man das Element undefined am selben Index. Beide Arrays haben die gleiche Länge.
> sparse.length 3 > dense.length 3
Aber das sparsame Array hat kein Element am Index 0.
> 0 in sparse false > 0 in dense true
Die Iteration über for ist für beide Arrays gleich:
> for (var i=0; i<sparse.length; i++) console.log(sparse[i]); undefined undefined c > for (var i=0; i<dense.length; i++) console.log(dense[i]); undefined undefined c
Die Iteration über forEach überspringt die Löcher, aber nicht die undefinierten Elemente:
> sparse.forEach(function (x) { console.log(x) });
c
> dense.forEach(function (x) { console.log(x) });
undefined
undefined
cEinige Operationen, die Arrays betreffen, ignorieren Löcher, während andere sie berücksichtigen. Dieser Abschnitt erklärt die Details.
forEach() überspringt Löcher:
> ['a',, 'b'].forEach(function (x,i) { console.log(i+'.'+x) })
0.a
2.bevery() überspringt ebenfalls Löcher (ähnlich: some()):
> ['a',, 'b'].every(function (x) { return typeof x === 'string' })
truemap() überspringt, bewahrt aber Löcher.
> ['a',, 'b'].map(function (x,i) { return i+'.'+x })
[ '0.a', , '2.b' ]filter() eliminiert Löcher:
> ['a',, 'b'].filter(function (x) { return true })
[ 'a', 'b' ]join() konvertiert Löcher, undefineds und nulls in leere Zeichenketten:
> ['a',, 'b'].join('-')
'a--b'
> [ 'a', undefined, 'b' ].join('-')
'a--b'sort() bewahrt Löcher während des Sortierens.
> ['a',, 'b'].sort() // length of result is 3 [ 'a', 'b', , ]
Die for-in-Schleife listet korrekt Eigenschaftsschlüssel auf (die eine Obermenge von Array-Indizes sind):
> for (var key in ['a',, 'b']) { console.log(key) }
0
2apply() wandelt jedes Loch in ein Argument um, dessen Wert undefined ist. Die folgende Interaktion zeigt dies: Die Funktion f() gibt ihre Argumente als Array zurück. Wenn wir apply() ein Array mit drei Löchern übergeben, um f() aufzurufen, erhält letzteres drei undefined-Argumente.
> function f() { return [].slice.call(arguments) }
> f.apply(null, [ , , ,])
[ undefined, undefined, undefined ]Das bedeutet, dass wir apply() verwenden können, um ein Array mit undefineds zu erstellen:
> Array.apply(null, Array(3)) [ undefined, undefined, undefined ]
apply() übersetzt Löcher in undefineds in leeren Arrays, aber es kann nicht verwendet werden, um Löcher in beliebigen Arrays zu füllen (die Löcher enthalten können oder nicht). Nehmen Sie zum Beispiel das beliebige Array [2].
> Array.apply(null, [2]) [ , ,]
Das Array enthält keine Löcher, daher sollte apply() dasselbe Array zurückgeben. Stattdessen gibt es ein leeres Array der Länge 2 zurück (es enthält nur zwei Löcher). Das liegt daran, dass Array() einzelne Zahlen als Array-Längen interpretiert, nicht als Array-Elemente.
Wie wir gesehen haben, entfernt filter() Löcher:
> ['a',, 'b'].filter(function (x) { return true })
[ 'a', 'b' ]Verwenden Sie eine benutzerdefinierte Funktion, um Löcher in beliebige Arrays in undefineds umzuwandeln.
functionconvertHolesToUndefineds(arr){varresult=[];for(vari=0;i<arr.length;i++){result[i]=arr[i];}returnresult;}
Verwendung der Funktion.
> convertHolesToUndefineds(['a',, 'b']) [ 'a', undefined, 'b' ]
Array.isArray(obj)
true zurück, wenn obj ein Array ist. Sie behandelt Objekte, die Realms (Fenster oder Frames) durchqueren, korrekt (im Gegensatz zu instanceof (siehe Fallstrick: Realme (Frames oder Fenster) durchqueren)).In den folgenden Abschnitten sind Array-Prototyp-Methoden nach Funktionalität gruppiert. Für jeden der Unterabschnitte erwähne ich, ob die Methodendestruktiv sind (sie ändern die Arrays, auf denen sie aufgerufen werden) odernicht-destruktiv sind (sie ändern ihre Empfänger nicht; solche Methoden geben oft neue Arrays zurück).
Alle Methoden in diesem Abschnitt sind destruktiv:
Array.prototype.shift()
Entfernt das Element am Index 0 und gibt es zurück. Die Indizes nachfolgender Elemente werden um 1 dekrementiert:
> var arr = [ 'a', 'b' ]; > arr.shift() 'a' > arr [ 'b' ]
Array.prototype.unshift(elem1?, elem2?, ...)
Stellt die gegebenen Elemente dem Array voran. Sie gibt die neue Länge zurück:
> var arr = [ 'c', 'd' ];
> arr.unshift('a', 'b')
4
> arr
[ 'a', 'b', 'c', 'd' ]Array.prototype.pop()
Entfernt das letzte Element des Arrays und gibt es zurück:
> var arr = [ 'a', 'b' ]; > arr.pop() 'b' > arr [ 'a' ]
Array.prototype.push(elem1?, elem2?, ...)
Fügt die gegebenen Elemente am Ende des Arrays hinzu. Sie gibt die neue Länge zurück:
> var arr = [ 'a', 'b' ];
> arr.push('c', 'd')
4
> arr
[ 'a', 'b', 'c', 'd' ]apply() (siehe Function.prototype.apply(thisValue, argArray)) ermöglicht es Ihnen, ein Array arr2 destruktiv an ein anderes Array arr1 anzuhängen:
> var arr1 = [ 'a', 'b' ]; > var arr2 = [ 'c', 'd' ]; > Array.prototype.push.apply(arr1, arr2) 4 > arr1 [ 'a', 'b', 'c', 'd' ]
Array.prototype.splice(start, deleteCount?, elem1?, elem2?, ...)
> var arr = [ 'a', 'b', 'c', 'd' ]; > arr.splice(1, 2, 'X'); [ 'b', 'c' ] > arr [ 'a', 'X', 'd' ]
Spezielle Parameterwerte
start kann negativ sein, in diesem Fall wird er zur Länge addiert, um den Startindex zu bestimmen. Somit bezieht sich -1 auf das letzte Element und so weiter.deleteCount ist optional. Wenn es weggelassen wird (zusammen mit allen nachfolgenden Argumenten), werden alle Elemente ab dem Index start entfernt.In diesem Beispiel entfernen wir alle Elemente nach und einschließlich des vorletzten Index.
> var arr = [ 'a', 'b', 'c', 'd' ]; > arr.splice(-2) [ 'c', 'd' ] > arr [ 'a', 'b' ]
Diese Methoden sind ebenfalls destruktiv.
Array.prototype.reverse()
Kehrt die Reihenfolge der Elemente im Array um und gibt eine Referenz auf das ursprüngliche (modifizierte) Array zurück:
> var arr = [ 'a', 'b', 'c' ]; > arr.reverse() [ 'c', 'b', 'a' ] > arr // reversing happened in place [ 'c', 'b', 'a' ]
Array.prototype.sort(compareFunction?)
Sortiert das Array und gibt es zurück:
> var arr = ['banana', 'apple', 'pear', 'orange']; > arr.sort() [ 'apple', 'banana', 'orange', 'pear' ] > arr // sorting happened in place [ 'apple', 'banana', 'orange', 'pear' ]
Beachten Sie, dass beim Sortieren Werte durch Umwandlung in Zeichenketten verglichen werden, was bedeutet, dass Zahlen nicht numerisch sortiert werden.
> [-1, -20, 7, 50].sort() [ -1, -20, 50, 7 ]
Sie können dies beheben, indem Sie den optionalen Parameter compareFunction angeben, der steuert, wie sortiert wird. Er hat die folgende Signatur:
functioncompareFunction(a,b)
Diese Funktion vergleicht a und b und gibt zurück:
-1), wenn a kleiner als b ist.a gleich b ist.1), wenn a größer als b ist.functioncompareCanonically(a,b){if(a<b){return-1;}elseif(a>b){return1;}else{return0;}}
Ich mag keine verschachtelten bedingten Operatoren. Aber in diesem Fall ist der Code so viel weniger ausführlich, dass ich versucht bin, ihn zu empfehlen:
functioncompareCanonically(a,b){returna<b?-1:(a>b?1:0);}
Verwendung der Funktion.
> [-1, -20, 7, 50].sort(compareCanonically) [ -20, -1, 7, 50 ]
Für Zeichenketten können Sie String.prototype.localeCompare verwenden (siehe Zeichenketten vergleichen).
> ['c', 'a', 'b'].sort(function (a,b) { return a.localeCompare(b) })
[ 'a', 'b', 'c' ]Der Parameter compareFunction ist auch nützlich zum Sortieren von Objekten:
vararr=[{name:'Tarzan'},{name:'Cheeta'},{name:'Jane'}];functioncompareNames(a,b){returna.name.localeCompare(b.name);}
Mit compareNames als Vergleichsfunktion wird arr nach name sortiert.
> arr.sort(compareNames)
[ { name: 'Cheeta' },
{ name: 'Jane' },
{ name: 'Tarzan' } ]Die folgenden Methoden führen verschiedene nicht-destruktive Operationen auf Arrays aus:
Array.prototype.concat(arr1?, arr2?, ...)
Erstellt ein neues Array, das alle Elemente des Empfängers enthält, gefolgt von allen Elementen des Arrays arr1 und so weiter. Wenn einer der Parameter kein Array ist, wird er als Element zum Ergebnis hinzugefügt (zum Beispiel das erste Argument, 'c', hier):
> var arr = [ 'a', 'b' ];
> arr.concat('c', ['d', 'e'])
[ 'a', 'b', 'c', 'd', 'e' ]Das Array, auf dem concat() aufgerufen wird, wird nicht geändert.
> arr [ 'a', 'b' ]
Array.prototype.slice(begin?, end?)
Kopiert Array-Elemente in ein neues Array, beginnend bei begin, bis zum und ausschließlich des Elements bei end:
> [ 'a', 'b', 'c', 'd' ].slice(1, 3) [ 'b', 'c' ]
Wenn end fehlt, wird die Array-Länge verwendet.
> [ 'a', 'b', 'c', 'd' ].slice(1) [ 'b', 'c', 'd' ]
Wenn beide Indizes fehlen, wird das Array kopiert.
> [ 'a', 'b', 'c', 'd' ].slice() [ 'a', 'b', 'c', 'd' ]
Wenn einer der Indizes negativ ist, wird die Array-Länge dazu addiert. Somit bezieht sich -1 auf das letzte Element und so weiter.
> [ 'a', 'b', 'c', 'd' ].slice(1, -1) [ 'b', 'c' ] > [ 'a', 'b', 'c', 'd' ].slice(-2) [ 'c', 'd' ]
Array.prototype.join(separator?)
Erstellt eine Zeichenkette, indem toString() auf alle Array-Elemente angewendet und die Zeichenkette separator zwischen die Ergebnisse gesetzt wird. Wenn separator weggelassen wird, wird ',' verwendet:
> [3, 4, 5].join('-')
'3-4-5'
> [3, 4, 5].join()
'3,4,5'
> [3, 4, 5].join('')
'345'join() konvertiert undefined und null in leere Zeichenketten.
> [undefined, null].join('#')
'#'Löcher in Arrays werden ebenfalls in leere Zeichenketten konvertiert.
> ['a',, 'b'].join('-')
'a--b'Die folgenden Methoden suchen nach Werten in Arrays:
Array.prototype.indexOf(searchValue, startIndex?)
> [ 3, 1, 17, 1, 4 ].indexOf(1) 1 > [ 3, 1, 17, 1, 4 ].indexOf(1, 2) 3
Gleichheitsprüfung (siehe Gleichheitsoperatoren: === vs. ==) wird für die Suche verwendet, was bedeutet, dass indexOf() NaN nicht finden kann:
> [NaN].indexOf(NaN) -1
Array.prototype.lastIndexOf(searchElement, startIndex?)
Durchsucht das Array nach searchElement, beginnend bei startIndex, rückwärts. Es gibt den Index des ersten Vorkommens zurück oder –1, wenn nichts gefunden wird. Wenn startIndex negativ ist, wird die Array-Länge dazu addiert; wenn es fehlt, wird das gesamte Array durchsucht. Gleichheitsprüfung (siehe Gleichheitsoperatoren: === vs. ==) wird für die Suche verwendet.
> [ 3, 1, 17, 1, 4 ].lastIndexOf(1) 3 > [ 3, 1, 17, 1, 4 ].lastIndexOf(1, -3) 1
Iterations-Methoden verwenden eine Funktion, um über ein Array zu iterieren. Ich unterscheide drei Arten von Iterationsmethoden, die alle nicht-destruktiv sind: Prüfungsmethoden beobachten hauptsächlich den Inhalt eines Arrays; Transformationsmethoden leiten ein neues Array aus dem Empfänger ab; und Reduktionsmethoden berechnen ein Ergebnis basierend auf den Elementen des Empfängers.
Jede Methode, die in diesem Abschnitt beschrieben wird, sieht so aus:
arr.examinationMethod(callback,thisValue?)
Eine solche Methode nimmt die folgenden Parameter an:
callback ist ihr erster Parameter, eine Funktion, die sie aufruft. Je nach Prüfungsmethode gibt der Callback einen Booleschen Wert zurück oder nichts. Er hat die folgende Signatur:
functioncallback(element,index,array)
element ist ein Array-Element, das die callback verarbeiten soll, index ist der Index des Elements und array ist das Array, auf dem examinationMethod aufgerufen wurde.
thisValue ermöglicht es Ihnen, den Wert von this innerhalb von callback zu konfigurieren.Und nun zu den Prüfungsmethoden, deren Signaturen ich gerade beschrieben habe:
Array.prototype.forEach(callback, thisValue?)
Iteriert über die Elemente eines Arrays.
vararr=['apple','pear','orange'];arr.forEach(function(elem){console.log(elem);});
Array.prototype.every(callback, thisValue?)
Dieses Beispiel prüft, ob jede Zahl im Array gerade ist.
> function isEven(x) { return x % 2 === 0 }
> [ 2, 4, 6 ].every(isEven)
true
> [ 2, 3, 4 ].every(isEven)
falseWenn das Array leer ist, ist das Ergebnis true (und callback wird nicht aufgerufen).
> [].every(function () { throw new Error() })
trueArray.prototype.some(callback, thisValue?)
Dieses Beispiel prüft, ob eine gerade Zahl im Array vorhanden ist.
> function isEven(x) { return x % 2 === 0 }
> [ 1, 3, 5 ].some(isEven)
false
> [ 1, 2, 3 ].some(isEven)
trueWenn das Array leer ist, ist das Ergebnis false (und callback wird nicht aufgerufen).
> [].some(function () { throw new Error() })
falseEin potenzieller Fallstrick von forEach() ist, dass es kein break oder etwas Ähnliches zur vorzeitigen Beendigung der Schleife unterstützt. Wenn Sie dies tun müssen, können Sie some() verwenden.
functionbreakAtEmptyString(strArr){strArr.some(function(elem){if(elem.length===0){returntrue;// break}console.log(elem);// implicit: return undefined (interpreted as false)});}
some() gibt true zurück, wenn ein Abbruch stattgefunden hat, und false andernfalls. Dies ermöglicht es Ihnen, unterschiedlich zu reagieren, je nachdem, ob die Iteration erfolgreich abgeschlossen wurde (was mit for-Schleifen etwas knifflig ist).
Transformations-Methoden nehmen ein Eingabearray und erzeugen ein Ausgabearray, wobei der Callback steuert, wie die Ausgabe erzeugt wird. Der Callback hat die gleiche Signatur wie für Prüfungsmethoden:
functioncallback(element,index,array)
Es gibt zwei Transformationsmethoden:
Array.prototype.map(callback, thisValue?)
Jedes Ausgabearray-Element ist das Ergebnis der Anwendung von callback auf ein Eingabeelement. Zum Beispiel:
> [ 1, 2, 3 ].map(function (x) { return 2 * x })
[ 2, 4, 6 ]Array.prototype.filter(callback, thisValue?)
Das Ausgabearray enthält nur die Eingabeelemente, für die callback true zurückgibt. Zum Beispiel:
> [ 1, 0, 3, 0 ].filter(function (x) { return x !== 0 })
[ 1, 3 ]Für die Reduktion hat der Callback eine andere Signatur:
functioncallback(previousValue,currentElement,currentIndex,array)
Der Parameter previousValue ist der von der Callback zuvor zurückgegebene Wert. Wenn die Callback zum ersten Mal aufgerufen wird, gibt es zwei Möglichkeiten (die Beschreibungen gelten für Array.prototype.reduce(); Unterschiede zu reduceRight() werden in Klammern erwähnt):
initialValue wurde bereitgestellt. Dann ist previousValue initialValue, und currentElement ist das erste Array-Element (reduceRight: das letzte Array-Element).initialValue wurde bereitgestellt. Dann ist previousValue das erste Array-Element, und currentElement ist das zweite Array-Element (reduceRight: das letzte Array-Element und das vorletzte Array-Element).Es gibt zwei Reduktionsmethoden.
Array.prototype.reduce(callback, initialValue?)
functionadd(prev,cur){returnprev+cur;}console.log([10,3,-1].reduce(add));// 12
Wenn Sie reduce auf einem Array mit einem einzigen Element aufrufen, wird dieses Element zurückgegeben.
> [7].reduce(add) 7
Wenn Sie reduce auf einem leeren Array aufrufen, müssen Sie initialValue angeben, andernfalls erhalten Sie eine Ausnahme.
> [].reduce(add) TypeError: Reduce of empty array with no initial value > [].reduce(add, 123) 123
Array.prototype.reduceRight(callback, initialValue?)
reduce(), aber iteriert von rechts nach links.In vielen funktionalen Programmiersprachen ist reduce als fold oder foldl (Left Fold) bekannt, und reduceRight ist als foldr (Right Fold) bekannt.
Eine andere Möglichkeit, die reduce-Methode zu betrachten, ist, dass sie einen n-stelligen Operator OP implementiert.
OP1≤i≤n xi
durch eine Reihe von Anwendungen eines binären Operators op2
(...(x1 op2 x2) op2 ...) op2 xn
Das ist, was im vorherigen Codebeispiel passiert ist: Wir haben einen n-stelligen Summenoperator für Arrays über den binären Plusoperator von JavaScript implementiert.
Als Beispiel untersuchen wir die beiden Iterationsrichtungen anhand der folgenden Funktion.
functionprintArgs(prev,cur,i){console.log('prev:'+prev+', cur:'+cur+', i:'+i);returnprev+cur;}
Wie erwartet, iteriert reduce() von links nach rechts.
> ['a', 'b', 'c'].reduce(printArgs) prev:a, cur:b, i:1 prev:ab, cur:c, i:2 'abc' > ['a', 'b', 'c'].reduce(printArgs, 'x') prev:x, cur:a, i:0 prev:xa, cur:b, i:1 prev:xab, cur:c, i:2 'xabc'
Und reduceRight() iteriert von rechts nach links.
> ['a', 'b', 'c'].reduceRight(printArgs) prev:c, cur:b, i:1 prev:cb, cur:a, i:0 'cba' > ['a', 'b', 'c'].reduceRight(printArgs, 'x') prev:x, cur:c, i:2 prev:xc, cur:b, i:1 prev:xcb, cur:a, i:0 'xcba'
Einige Objekte in JavaScript sehen aus wie Arrays, sind es aber nicht. Das bedeutet normalerweise, dass sie indizierten Zugriff und eine length-Eigenschaft haben, aber keine der Array-Methoden. Beispiele hierfür sind die spezielle Variable arguments, DOM-Knotenlisten und Zeichenketten. Array-ähnliche Objekte und generische Methoden gibt Tipps zur Arbeit mit array-ähnlichen Objekten.
Um ein Array arr zu durchlaufen, haben Sie zwei Möglichkeiten:
Eine einfache for-Schleife (siehe for).
for(vari=0;i<arr.length;i++){console.log(arr[i]);}
Eine der Array-Iterationsmethoden (siehe Iteration (nicht-destruktiv)). Zum Beispiel forEach().
arr.forEach(function(elem){console.log(elem);});
Verwenden Sie nicht die for-in-Schleife (siehe for-in), um Arrays zu durchlaufen. Sie iteriert über Indizes, nicht über Werte. Und sie schließt die Schlüssel normaler Eigenschaften ein, einschließlich vererbter.