2009-05-13 6 views
2

Puh! Das war ein langer Titel.For-Loop-Einstellung Länge Variable beim Konvertieren von Nodelist

lese ich WROX‘Buch über Professional JavaScript für Web-Entwickler und ich kam in diesem Beispielcode, und ich habe mich nur gefragt, ob das beste Praxis war:

function convertToArray(nodes) { 
    array = new Array(); 
    for (var i=0, len=nodes.length; i < len; i++) { 
     array.push(nodes[i]); 
    } 
    return array; 
} 

Das Ding, das habe hat mich mein Kratzen Kopf ist die "len = nodes.length". Habe ich falsch gedacht, dass der erste Satz in einer For-Schleife nur einmal ausgeführt wird? Gibt es einen Grund, warum Sie eine Variable (len) auf die Länge der nodeList setzen möchten, bevor Sie sie durchlaufen? Würdest du das auch mit einem normalen Array machen?

Danke

Antwort

6

Das ist aus Leistungsgründen. Eine lokale Variable ist aus mehreren Gründen schneller:

  • Auf die Länge muss die ganze Zeit in der Schleife zugegriffen werden, einmal pro Iteration;
  • Eine lokale Variablensuche ist schneller als die Membersuche;
  • Wenn nodes ein Array ist, dann ist .length eine magische Eigenschaft, die etwas länger als eine Membervariable abgerufen werden kann.
  • Wenn nodes ein ActiveX-Objekt ist, dann kann .length zu einem Methodenaufruf in das Objekt führen, also ist dies die teuerste Operation von allen.
3

Während wir Mikro-Optimierungen besprechen, sollte die folgende sein noch schneller:

function convertToArray(nodes) { 
    var i = nodes.length, 
     array = new Array(i); // potentially faster than `array = []` 
           // -- see comments 

    while(i--) 
     array[i] = nodes[i]; 

    return array; 
} 

Es braucht man weniger lokale Variable verwendet einen while und keine for Schleife und verwendet Array Zuweisung statt der Funktionsaufruf push().

Auch, weil wir zählen nach unten wir vorbelegt die Slots des Arrays, die Länge des Array muss nicht bei jeder Iteration Schritt geändert werden, aber nur auf dem ersten.

+0

sarnath'd - well put sir – annakata

+0

Dies kann noch weiter optimiert werden, indem "array = []" durch "array = new Array (nodes.length)" ersetzt wird. Auf diese Weise muss das Array nicht ständig wachsen (was zu Speicherzuweisungen führt). –

+0

@Vilx: Ich denke du hast Recht; Beachten Sie jedoch, dass das Analysieren des Array-Literals schneller ist als das Aufrufen des Konstruktors, und solange "node.length" nicht "zu groß" ist, wird die erste Zuweisung weiterhin ein dichtes Array erstellen (die meisten JS-Engines unterscheiden zwischen dicht und dünn) Arrays), also könnte es stattdessen einen Performance-Hit geben ... – Christoph