2015-07-08 11 views
18

Trong ES6, iterable là một đối tượng cho phép for... of và có khóa Symbol.iterator.HTMLCollection và NodeList có thể lặp lại không?

Mảng có thể lặp lại, như là Bộ và Bản đồ. Câu hỏi đặt ra là: HTMLCollectionNodeList có thể lặp lại không? Chúng được cho là?

Tài liệu MDN dường như đề xuất một NodeList là một lần lặp lại.

for...of vòng lặp trên NodeList sẽ các đối tượng một cách chính xác, trong các trình duyệt có hỗ trợ for...of (như Firefox 13 và sau)

Điều này dường như để chứng thực hành vi của Firefox.

Tôi đã thử nghiệm mã sau trong cả Chrome và Firefox và ngạc nhiên khi thấy rằng Firefox dường như nghĩ rằng chúng có thể lặp lại, nhưng Chrome thì không. Ngoài ra, Firefox cho rằng các trình vòng lặp được trả về bởi HTMLCollectionNodeList là một và giống nhau.

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>

Một thực sự kỳ lạ, khó hiểu điều: chạy đoạn mã tạo ra một kết quả khác nhau từ sao chép nó và chạy trong một tập tin thực tế/console trong Firefox (đặc biệt là so sánh cuối cùng). Bất kỳ sự giác ngộ nào về hành vi kì lạ này cũng sẽ được đánh giá cao.

+4

Nó không phải là một iterable trong Chrome, nhưng nó được coi là. Xem [Vấn đề 401699: Thêm hỗ trợ trình lặp cho NodeList và bạn bè] (https://code.google.com/p/chromium/issues/detail?id=401699) – lyschoening

+0

Bạn có thể muốn xem [NodeList.js] (https : //github.com/eorroe/NodeList.js) –

+1

Nó cũng không thể lặp lại trong Safari. – Barmar

Trả lời

4

Symbol.iterator hỗ trợ cho NodeList, HTMLCollection, DOMTokenList, và DOMSettableTokenListdiscussedadded vào năm ngoái WHATWG's DOM spec.

+1

Về mặt kỹ thuật, ES6 và WHATWG là các ủy ban khác nhau. Ủy ban ES6 coi WHATWG là điểm khởi đầu của ES5 và các tiêu chuẩn phát triển từ đó khi bỏ qua WHATWG từ thời điểm đó trở đi.Tuy nhiên có những người là thành viên của cả hai ủy ban vì vậy tôi mong rằng nó sẽ được đề xuất cho ủy ban ES6 tại một thời điểm nào đó (mặc dù có nhiều khả năng được đề xuất cho ES7 vì ES7 ở chế độ nháp trong khi ES6 được coi là "cuối cùng") – slebetman

+1

Về mặt kỹ thuật, không phải ES6 hay WHATWG là một ủy ban. TC39 là một ủy ban tiêu chuẩn hóa ECMAScript. Và WHATWG là một cộng đồng tiêu chuẩn hóa các lớp được đề cập. TC39 không có tham vọng để chuẩn hóa các lớp này. – Anne

5

Thật không may, chưa. Nhưng cho đến khi họ đang có, bạn có thể dễ dàng polyfill họ như vậy:

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

Yup, đó chính xác là những gì tôi đang làm bây giờ cho 'HTMLCollection' và 'NodeList'. Nó chỉ là lạ mà Chrome/Opera không xem xét chúng iterables trong khi Firefox nào. Từ các bình luận cho đến nay, tôi đoán chúng được cho là, nhưng tôi không thể chắc chắn 100%. – light

2

Như greiner chỉ ra, có nguồn gốc Symbol.iterator hỗ trợ cho NodeList đã được thêm vào DOM đặc tả của WHATWG trong năm 2014.

Thật không may, Chrome 51 là phiên bản đầu tiên của Chrome để hỗ trợ nó và bản Beta của nó vừa được phát hành tại thời điểm viết câu trả lời này. Ngoài ra, không có hỗ trợ trong bất kỳ phiên bản nào của Internet Explorer hoặc Edge.

Để thêm Symbol.iterator hỗ trợ cho NodeList trong tất cả các trình duyệt mã của bạn, chỉ cần sử dụng polyfill sau:

NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator]; 
Các vấn đề liên quan