javascript - titel - title tag länge 2018




Wie initialisiert man die Länge eines Arrays in Javascript? (11)

  1. Warum möchten Sie die Länge initialisieren? Theoretisch ist das nicht nötig. Es kann sogar zu einem verwirrenden Verhalten führen, da alle Tests, die die length , um herauszufinden, ob ein Array leer ist oder nicht, melden, dass das Array nicht leer ist.
    Some tests zeigen, dass das Festlegen der Anfangslänge von großen Arrays effizienter sein kann, wenn das Array danach gefüllt wird, aber der Leistungsgewinn (falls vorhanden) scheint sich von Browser zu Browser zu unterscheiden.

  2. jsLint mag das new Array() weil der Konstruktor mehrdeutig ist.

    new Array(4);
    

    erstellt ein leeres Array der Länge 4. Aber

    new Array('4');
    

    erstellt ein Array mit dem Wert '4' .

Zu deinem Kommentar: In JS brauchst du die Länge des Arrays nicht zu initialisieren. Es wächst dynamisch. Sie können die Länge einfach in einer Variablen speichern, z

var data = [];
var length = 5; // user defined length

for(var i = 0; i < length; i++) {
    data.push(createSomeObject());
}

Die meisten Tutorials, die ich auf 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 eine Ganzzahl übergeben, indem Sie var test = new Array(4); Syntax.

Nachdem ich diese Syntax großzügig in meinen js-Dateien benutzt habe, habe ich eine der Dateien durch jsLint , und es ist ausgeflippt:

Fehler: Problem bei Zeile 1 Zeichen 22: Erwartet ')' und stattdessen '4'.
var test = neues Array (4);
Problem bei Zeile 1 Zeichen 23: Erwartet ';' und sah stattdessen ')'.
var test = neues Array (4);
Problem bei Zeile 1 Zeichen 23: Erwartete eine Kennung und stattdessen ')'.

Nach dem Lesen von jsLints Erklärung seines Verhaltens sieht es so aus, als ob jsLint die new Array() -Syntax nicht wirklich mag und stattdessen [] bei der Deklaration von Arrays bevorzugt.

Also habe ich ein paar Fragen. Erstens, warum? Gehe ich irgendein Risiko, indem ich stattdessen die new Array() Syntax verwende? Gibt es Browser-Inkompatibilitäten, auf die ich achten sollte? Und zweitens, wenn ich zur eckigen Klammersyntax wechsele, gibt es irgendeine Möglichkeit, ein Array zu deklarieren und seine Länge auf eine Zeile zu setzen, oder muss ich etwas in der Art tun:

var test = [];
test.length = 4;

(das war wahrscheinlich besser als Kommentar, aber zu lange)

Nachdem ich das gelesen hatte, war ich neugierig, ob das Vorabzuteilen tatsächlich schneller war, weil es theoretisch so sein sollte. Allerdings gab dieser Blog einige Tipps, die dagegen sprechen http://www.html5rocks.com/en/tutorials/speed/v8/ .

Da ich mich immer noch unsicher bin, stelle ich es auf die Probe. Und wie sich herausstellt, scheint es tatsächlich langsamer zu sein.

var time = Date.now();
var temp = [];
for(var i=0;i<100000;i++){
    temp[i]=i;
}
console.log(Date.now()-time);


var time = Date.now();
var temp2 = new Array(100000);
for(var i=0;i<100000;i++){
    temp2[i] = i;
}
console.log(Date.now()-time); 

Dieser Code führt nach ein paar gelegentlichen Läufen zu folgendem Ergebnis:

$ node main.js 
9
16
$ node main.js 
8
14
$ node main.js 
7
20
$ node main.js 
9
14
$ node main.js 
9
19

Dadurch wird die Längeneigenschaft auf 4 initialisiert:

var x = [,,,,];

Der Array-Konstruktor hat eine mehrdeutige Syntax und JSLint verletzt nur Ihre Gefühle.

Außerdem ist Ihr Beispielcode defekt, die zweite var Anweisung SyntaxError einen SyntaxError . Sie legen die Eigenschaftslänge des Array- test , sodass keine weitere var erforderlich ist.

Soweit Ihre Möglichkeiten gehen, ist array.length die einzige "saubere". Frage ist, warum müssen Sie die Größe an erster Stelle einstellen? Versuchen Sie, Ihren Code neu zu strukturieren, um diese Abhängigkeit zu beseitigen.


Der kürzeste:

[...Array(1000)]

ES6 führt Array.from dem Sie ein Array aus beliebigen Array-ähnlichen oder iterierbaren Objekten erstellen können:

Array.from({length: 10}).map((x, i) => i);
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In diesem Fall stellt {length: 10} die minimale Definition eines "array-like" -Objekts dar: ein leeres Objekt mit nur einer length .


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:

var test = _.map(_.range(4), function () { return undefined; });
console.log(test.length);

Aus den oben erwähnten Gründen würde ich dies vermeiden, wenn ich das Array nicht auf einen bestimmten Wert initialisieren möchte. Es ist interessant festzustellen, dass es andere Bibliotheken gibt, die einen Bereich einschließlich Lo-Dash und Lazy implementieren, die unterschiedliche Leistungsmerkmale aufweisen können.


Mit ES2015 .fill() Sie jetzt einfach:

//n is the size you want to initialize your array
Array(n).fill(0)

Das ist viel prägnanter als Array.apply(0, new Array(n)).map(i => 0)


Wie oben erläutert, ist die Verwendung eines new Array(size) etwas gefährlich. Anstatt es direkt zu verwenden, platzieren Sie es innerhalb einer "Array-Creator-Funktion". Sie können leicht sicherstellen, dass diese Funktion fehlerfrei ist, und Sie vermeiden die Gefahr, direkt ein new Array(size) aufzurufen. Sie können ihm auch einen optionalen Standardanfangswert geben. Diese createArray Funktion macht genau das:

function createArray(size, defaultVal) {
    var arr = new Array(size);
    if (arguments.length == 2) {
        // optional default value
        for (int i = 0; i < size; ++i) {
            arr[i] = defaultVal;
        }
    }
    return arr;
}

[...Array(6)].map(x=>0);

// [0, 0, 0, 0, 0, 0]

ODER

Array(6).fill(0);

// [0, 0, 0, 0, 0, 0]

ODER

Array(6).fill(null).map( (x,i) => i );

// [0, 1, 2, 3, 4, 5]

( Typoskript sicher )

Verschachtelte Arrays erstellen

Wenn Sie ein 2D- Array mit der fill intuitiv erstellen, sollten Sie neue Instanzen erstellen. Aber was tatsächlich passiert ist, dass das gleiche Array als Referenz gespeichert wird.

var a = Array(3).fill([6]); 
// [[6], [6], [6]]

a[ 0 ].push( 9 );
// [[6,9], [6,9], [6,9]]

Lösung

var a = [...Array(3)].map(x=>[]); 

a[ 0 ].push( 4, 2 );
// [[4,2], [ ], [ ]]

Ein 3x2-Array wird also ungefähr so ​​aussehen:

[...Array(3)].map(x=>Array(2).fill(0));

// [ [0,0] ,
//   [0,0] ,
//   [0,0] ]

  • Array(5) gibt Ihnen ein Array mit der Länge 5, aber keine 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 undefiniert als Werte, jetzt kann es iteriert 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 Warnungen

  • ES6 gibt uns Array.from so dass Sie auch Array.from(Array(5)).forEach(alert)

  • Wenn Sie mit einem bestimmten Wert initialisieren möchten, sind diese gut zu wissen ...
    Array.from('abcde') , Array.from('x'.repeat(5))
    oder Array.from({length: 5}, (v, i) => i) // gives [0, 1, 2, 3, 4]







jslint