2015-07-10 20 views
9

Ich verwende eine ForEach, um eine NodeList durchlaufen. Mein Code ist wie folgtVerwenden von Js ForEach mit einer NodeList

var array = document.querySelectorAll('items'); 

array.forEach(function (item) { 
    console.log(item); 
}); 

Und dieser Code wirft einen Fehler als

Uncaught TypeError: array.forEach is not a function

Dann nach einigen Online-Blog-Artikel zu lesen ich den Code auf das geändert.

[].forEach.call(array, (function (item) { 
    console.log(item); 
})); 

Könnte jemand bitte erklären, warum es nicht möglich ist forEach auf einem nodeList zu nennen und etwas das obige zweite Code Stück zu tun hat. :)

+0

Check out [NodeList.js] nutzen wollte (https://github.com/eorroe/NodeList.js) –

+1

Probieren Sie diese eine Zeile NodeList Patch http://StackOverflow.com/a/32644632/502860 – imos

Antwort

8

Dies ist eine grundlegende Sache in JavaScript: Sie können eine Funktion von einem Objekt und anwenden auf ein anderes Objekt. Das heißt: Rufen Sie es mit this auf das Objekt setzen Sie die Funktion an. Das ist möglich, weil in JavaScript alle Property-Namen usw. (einfach ausgedrückt) namentlich identifiziert werden. Also trotz NodeList.length ist etwas anderes als Array.length die Funktion Array.forEach kann angewendet werden auf alles, was die Eigenschaft length (und andere Sachen, die forEach erfordert).

Also, was in Ihrem Fall passiert ist, dass:

  • querySelectorAll() ein Objekt vom Typ zurück NodeList, die length Eigenschaft belichten passiert ist und durchlaufen (lassen Sie uns sagen, dass es durch [] Bediener zugänglich ist); NodeList nicht forEach Funktion (wie Sie i.e hier: https://developer.mozilla.org/en-US/docs/Web/API/NodeList) - das ist, warum es unmöglich ist, forEach auf den Ergebnissen der querySelectorAll()
  • [].forEach gibt eine Funktion direkt aufrufen - das ist ein nicht so klug Abkürzung für Array.prototype.forEach
  • mit [].forEach.call(array, …) diese Funktion auf eine angewendet wird Objekt durch array Bezug genommen wird, ein Objekt vom Typ NodeList (dh forEach mit array als this in Funktionskörpern aufgerufen wird, so dass, wenn es im Inneren forEachthis.length ist es bezieht sich auf length in array trotz arrayNodeList und nicht real Array)
  • dies funktioniert, weil forEach verwendet Eigenschaften sind, die Array und NodeList gemeinsam haben; es würde scheitern, wenn, das heißt forEach eine Eigenschaft, die Array, aber NodeList hat nicht
4

Das NodeList Objekt enthält nicht die Methode forEach, es ist eine Methode der Array object. der folgende Code:

[].forEach.call(array, (function (item) { 
    console.log(item); 
})); 

wird unter Verwendung der Methode von forEach Array und ein NodeList geben.

Eine weitere Option, die Sie haben, und arguabiliy besser ist Ihr NodeList in ein Array zu konvertieren, wie folgt aus:

var myArrayOfNodes = [].slice.call(NodeList); 

Dies nutzt die Array-Objekte slicemethod eine Reihe von Knoten aus einem NodeList zu erstellen. Dies ist ein besserer Ansatz, da Sie dann ein Array verwenden können, anstatt ein Array-ähnliches Objekt zu hacken.

-1

querySelectorAll Ruft das Element in array-like Objekt nicht ein Array. Sie müssen also wie im zweiten Codebeispiel verwenden.

+0

Kraft der Ente Eingabe –

+0

Entschuldigung, was meinst du? –

+0

https://en.wikipedia.org/wiki/Duck_typing – atmd