2013-04-25 8 views
10

Was ist der Unterschied zwischen der Verwendung von document.head und der Verwendung von document.getElementsByTagName("head")[0]? Tests, die ich durchgeführt habe, haben gezeigt, dass beide eine Millisekunde benötigen.document.head v. Document.getElementsByTagName ("Kopf") [0]

Ich habe auch

gesehen
document.head||document.getElementsByTagName("head")[0]; 

, die mich geführt hätte, zu glauben, dass document.head schneller ist und das andere ist mehr kompatibel, Ausnahme, dass die Tests, die ich diese widerlegt hat.

Und wenn einer kompatibler ist, warum auch den anderen?

Update: Meine Tests waren falsch, wie einige darauf hingewiesen haben.

+0

Sie können auch 'document.querySelector (" head ")' '. Es ist nur eine Frage der Wahl. –

+0

Es kann nicht viel schneller als eine direkte Referenz werden. Also sollte 'document.head' um eine Größenordnung schneller sein, siehe http://jsperf.com/document-head-vs-getelementsbytagname – jAndy

Antwort

10

Mit dem || Operator wie das ist eine Form der Feature-Erkennung. Wenn der erste Wert nicht definiert ist, sendet er den letzten Wert zurück.

Also für

document.head || document.getElementsByTagName("head")[0]; 

der Grund ist, dass, wenn document.head nicht zumindest der rechte Wert unterstützt wird zurückgegeben.

Wie bei Ihrem Geschwindigkeitstest ist eine Millisekunde eine lange Zeit. Ich bezweifle, dass es wirklich so lange gedauert hat. Tatsächlich habe ich dafür einen jsPerf gemacht. Es zeigt, dass die getElementsByTagName Funktion etwa 80% langsamer ist.

+2

stimme zu, dass sie nicht ' t nimmt die gleiche Zeit, 'getElementsByTagName' wird langsamer, wenn die DOM-Größe zunimmt. Und '1ms' ist ein Zeichen, dass es schlecht gemessen wurde. –

+0

Ja, ich benutzte' console.time() 'in FF ... –

+1

@Sortofabegner' console.time() 'ist gut genug für diesen Zweck, aber du ' d muss mehr als einmal messen, um anständige Genauigkeit zu erhalten –

2

Dies ist mehr eine Bequemlichkeit Angelegenheit als eine Leistung (obwohl document.head sollte einen vernachlässigbaren Nutzen haben). Verwenden Sie, was immer Sie möchten, oder verwenden Sie eine als Fallback für die andere (wie Ihr Beispiel-Code). Der Fallback ist klug, da document.head nicht in IE 6-8 unterstützt wird.

Es ist nicht wahrscheinlich, dass getElementsByTagName bald veraltet sein wird, also ist dies kein gutes Beispiel dafür, wann es gut ist, einen Fallback bereitzustellen. Sie können sicher die ausführlichere Route alleine nutzen und Unterstützung in die Zukunft genießen.

Bessere Beispiele für diese Art von Dingen wären Ereignisse und wie sie in modernen Browsern im Vergleich zu älteren Browsern herumgereicht werden. Es ist nicht ungewöhnlich, so etwas zu sehen:

function callback (event) { 
    var id = (event || window.event).target.id; 
} 

In diesem Fall jedoch der window.event Teil ist für Legacy-Unterstützung notwendig. Wenn das Objekt eventundefined ist, nehmen wir an, dass das Ereignis ein Mitglied auf dem Objekt window ist. Wenn Browser älter werden, hört window.event auf eine Sache zu sein, und diese Tests geben einstimmig stattdessen event.target.id zurück.

Wieder ist Ihr Fall ein bisschen anders, da getElementsByTagName wahrscheinlich nie veraltet oder verschwinden wird, wie window.event tat.

+0

Ich denke nicht, dass eine ~ 83% Performance-Strafe * nur * eine Frage der Bequemlichkeit ist. http://jsperf.com/document-head-vs-getelementsbytagname – jAndy

+2

@jAndy ~ 83% auf dieser Skala ist vernachlässigbar. Dies ist nicht die Art der Voroptimierung, über die sich Entwickler im Allgemeinen Gedanken machen müssen. – Sampson

+2

Ich stimme nicht zu. Ich würde erwarten, so schnell wie irgend möglich nach DOM-Elementen zu suchen, da diese Art von Operation tausende Male vorkommen kann. – jAndy

4

Nach MDN, document.head nur gewonnen Unterstützung in IE 9, so die andere Methode verwendet als Ausweich Sie schützt vor Browser

+0

Aber wenn 'document.getElementsByTagName (" head ") [0]' kompatibler ist, warum sollte 'document.head' überhaupt verwendet werden? –

+0

@Sortofabeginner Weil es kürzer und einfacher zu lesen ist. Es gibt mehrere Möglichkeiten, das DOM abzufragen. In einigen Fällen kann der * andere Weg * veraltet sein. Ich vermute nicht, dass das in diesem Fall passieren wird. – Sampson

1

Nur Bequemlichkeit Inkompatibilitäten, weil Sie nur eine pro Seite haben sollen. Genauso wie es eine direkte Verknüpfung zu document.body gibt, obwohl document.body Standard ist und Sie das Fallback nicht benötigen würden.

document.body || document.getElementsByTagName("body")[0] 

Ich würde document.head nicht verwenden, außer Sie IE9 + nur unterstützen. Bis dahin würde ich bleibe document.getElementsByTagName("head")[0]

Wenn Sie eine Version möchten, die Sie müssen nicht wie die Zeit vergeht ändern, können Sie die folgenden am Anfang des Skripts tun

document.head = document.head || document.getElementsByTagName("head")[0]; 

Auf diese Weise Sie können nur diesen einen Ort ändern, wenn Sie die Unterstützung für IE8 abbrechen (oder es sogar dort lassen, da es nicht wehtut, aber es wird ein toter Code sein).Der obige Code würde auch sicherstellen, dass Sie nur das DOM einmal abfragen

+0

Sie setzen Körper statt Kopf. –

+0

@Sortofabeginner Danke, repariere es. –

+1

Sie haben es nur an einem Ort repariert - es gibt mehrere andere Instanzen. –