2015-07-08 12 views
18

In ES6, un iterable è un oggetto che consente for... of e ha una chiave Symbol.iterator.Sono iterabili HTMLCollection e NodeList?

Gli array sono iterabili, come lo sono Set e Maps. La domanda è: sono HTMLCollection e NodeList iterables? Dovrebbero essere?

La documentazione MDN sembra suggerire un NodeList un iterabile.

for...of loop in loop oltre NodeList correttamente gli oggetti, nei browser che supportano for...of (come Firefox 13 e successive)

questo sembra corroborare il comportamento di Firefox.

Ho testato il seguente codice in Chrome e Firefox e sono rimasto sorpreso nel constatare che Firefox sembra pensare che siano iterabili, ma Chrome no. Inoltre, Firefox ritiene che gli iteratori restituiti da HTMLCollection e NodeList siano la stessa cosa.

var col = document.getElementsByClassName('test'); // Should get HTMLCollection of 2 elems 
 
var nod = document.querySelectorAll('.test');  // Should get NodeList of 2 elems 
 
var arr = [].slice.call(col);      // Should get Array of 2 elems 
 

 
console.log(col[Symbol.iterator]); // Firefox: iterator function, Chrome: undefined 
 
console.log(nod[Symbol.iterator]); // Firefox: iterator function, Chrome: undefined 
 
console.log(arr[Symbol.iterator]); // Firefox & Chrome: iterator function 
 
console.log(col[Symbol.iterator] === nod[Symbol.iterator]); // Firefox: true 
 
console.log(col[Symbol.iterator] === arr[Symbol.iterator]); // Firefox: false
<div class="test">1</div> 
 
<div class="test">2</div>

Uno davvero strano, confondendo cosa: in esecuzione il frammento di codice produce un risultato diverso da copiandolo e funzionante in un vero e proprio file/console in Firefox (in particolare lo scorso confronto). Anche l'illuminazione su questo strano comportamento qui sarebbe apprezzata.

+4

Non è un iterabile in Chrome, ma si suppone che sia. Vedi [Edizione 401699: supporto iteratore per NodeList e amici] (https://code.google.com/p/chromium/issues/detail?id=401699) – lyschoening

+0

Si potrebbe voler controllare [NodeList.js] (https : //github.com/eorroe/NodeList.js) –

+1

Non è neanche un iterabile in Safari. – Barmar

risposta

4

Symbol.iterator supporto per NodeList, HTMLCollection, DOMTokenList, e DOMSettableTokenList era discussed e added all'ultimo WHATWG's DOM spec anno.

+1

Tecnicamente parlando, ES6 e WHATWG sono diversi comitati. Il comitato ES6 considera WHATWG semplicemente come il punto di partenza di ES5 e gli standard evolvono da lì ignorando WHATWG da quel momento in poi.Tuttavia ci sono persone che fanno parte di entrambe le commissioni, quindi mi aspetterei che a un certo punto venga suggerito al comitato ES6 (anche se è più probabile che venga suggerito a ES7 poiché ES7 è in modalità bozza mentre ES6 è considerato "definitivo" – slebetman

+1

Bene, tecnicamente parlando né ES6 né WHATWG è un comitato. TC39 è un comitato che standardizza ECMAScript. E WHATWG è una comunità che standardizza le classi in questione. TC39 non ha alcuna ambizione di standardizzare queste classi. – Anne

5

Sfortunatamente, non ancora. Ma fino a quando non sono, si può facilmente Polyfill in questo modo:

HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator]; 
+0

Sì, questo è esattamente quello che sto facendo ora per 'HTMLCollection' e' NodeList'. È strano che Chrome/Opera non li consideri iterabili mentre Firefox lo fa. Dai commenti fino ad ora, immagino che dovrebbero essere, ma non posso essere sicuro al 100%. – light

2

Come greiner sottolineato, nativo Symbol.iterator supporto per NodeList è stato aggiunto al DOM spec del WHATWG nel 2014.

Purtroppo, Chrome 51 è il prima versione di Chrome per supportarlo e la sua Beta è stata appena rilasciata al momento della stesura di questa risposta. Inoltre, non c'è supporto in nessuna versione di Internet Explorer o Edge.

Per aggiungere il supporto per Symbol.iteratorNodeList in tutti i browser per il vostro codice, basta usare il seguente polyfill:

NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator]; 
Problemi correlati