2015-07-08 13 views
18

W ES6 obiekt for... of jest obiektem, który ma klucz Symbol.iterator.Czy są to iterables HTMLCollection i NodeList?

Tablice są iterables, podobnie jak zestawy i mapy. Pytanie brzmi: czy iterables są HTMLCollection i NodeList? Czy oni powinni być?

Dokumentacja MDN wydaje się sugerować, że NodeList jest iterable.

for...of pętle będzie pętla na liście węzłów obiektów poprawnie w przeglądarkach obsługujących for...of (jak Firefox 13 i później)

To wydaje się potwierdzać zachowanie Firefoksa.

Przetestowałem poniższy kod zarówno w przeglądarce Chrome, jak i Firefox. Zaskoczyło mnie, że Firefox wydaje się, że są to iterables, ale Chrome nie. Ponadto Firefox uważa, że ​​iteratory zwrócone przez HTMLCollection i NodeList są jednym i tym samym.

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>

One naprawdę dziwne, mylące rzeczą: bieganie fragment kodu daje inny wynik z kopiowanie i działa w rzeczywistym pliku/konsoli w Firefoksie (szczególnie ostatni porównanie). Powinno być docenione również wszelkie oświecenie w tym dziwnym zachowaniu.

+4

to nie jest iterable w Chrome, ale to ma być. Zobacz [Wydanie 401699: Dodaj obsługę iteratora do NodeList i znajomych] (https://code.google.com/p/chromium/issues/detail?id=401699) – lyschoening

+0

Możesz chcieć sprawdzić [NodeList.js] (https : //github.com/eorroe/NodeList.js) –

+1

To też nie jest możliwe do sprawdzenia w Safari. – Barmar

Odpowiedz

4

Symbol.iterator wsparcie dla NodeList, HTMLCollection, DOMTokenList i DOMSettableTokenList był discussed i added do ostatniego roku WHATWG's DOM spec.

+1

Z technicznego punktu widzenia ES6 i WHATWG to różne komisje. Komitet ES6 uważa WHATWG za zaledwie punkt wyjścia ES5, a standardy ewoluują stąd, ignorując WHATWG od tego momentu.Nadal są ludzie, którzy są członkami obu komitetów, więc spodziewam się, że zostanie to zasugerowane komisję ES6 w pewnym momencie (chociaż jest bardziej prawdopodobne, że zostanie zasugerowane ES7, ponieważ ES7 jest w trybie draftowym, a ES6 jest uważane za "ostateczne") – slebetman

+1

Cóż, technicznie rzecz biorąc ani ES6, ani WHATWG nie są komitetem. TC39 to komitet, który standaryzuje ECMAScript. WHATWG to społeczność, która standaryzuje klasy, o których mowa. TC39 nie ma ambicji standaryzacji tych klas. – Anne

5

Niestety, jeszcze nie. Ale dopóki nie są, można łatwo PolyFill je tak:

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

Tak, właśnie to robię teraz dla 'HTMLCollection' i 'NodeList'. To po prostu dziwne, że Chrome/Opera nie uważa ich za pliki iterables, podczas gdy Firefox je obsługuje. Z komentarzy do tej pory, myślę, że tak powinno być, ale nie mogę być w 100% pewny. – light

2

Jak greiner wskazał, native Symbol.iterator wsparcie dla NodeList został dodany do WHATWG za DOM specyfikacji w 2014

niestety Chrome 51 jest Pierwsza wersja Chrome do obsługi, a jego wersja beta została wydana dopiero w momencie pisania tej odpowiedzi. Ponadto nie ma obsługi w żadnej wersji przeglądarki Internet Explorer lub Edge.

Aby dodać Symbol.iterator wsparcie dla NodeList we wszystkich przeglądarkach do kodu, wystarczy kliknąć na poniższy PolyFill:

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