迭代器容許咱們在第一次調用next()
函數以後,再執行相應的邏輯。在上面的例子裏,當咱們調用迭代器的瞬間,咱們就馬上執行了排序和取值的工做。可是,若是next()
函數永遠不被調用的話,咱們就浪費了性能。因此讓咱們來優化它:es6
1 table[Symbol.iterator] = function () { 2 var _this = this; 3 var keys = null; 4 var index = 0; 5 6 return { 7 next: function () { 8 if (keys === null) { 9 keys = Object.keys(_this).sort(); 10 } 11 12 return { 13 value: keys[index], done: index++ >= keys.length 14 }; 15 } 16 } 17 }
for-of
和for-in
的差異segmentfault
理解for-of
和for-in
之間的差異,是十分重要的。如下是一個簡單的,可是很是好的解釋差異的例子:數組
1 var list = [3, 5, 7]; 2 list.foo = 'bar'; 3 4 for (var key in list) { 5 console.log(key); // 0, 1, 2, foo 6 } 7 8 for (var value of list) { 9 console.log(value); // 3, 5, 7 10 }
正如所見的,for-of
循環僅打印出了數組中的值,忽略了其餘屬性。這是由於數組的迭代器只返回其中預期的元素。函數
String
,Array
,TypedArray
,Map
和Set
都是內置迭代器,由於它們的原型中都有一個Symbol.iterator
方法。oop
1 var string = "hello"; 2 3 for (var chr of string) { 4 console.log(chr); // h, e, l, l, o 5 }
解構操做一樣也接受一個迭代器:性能
1 var hello = 'world'; 2 var [first, second, ...rest] = [...hello]; 3 console.log(first, second, rest); // w o ["r","l","d"]
只要永遠不返回done: true
,就實現了一個無限迭代器。固然,須要極力避免出現這種狀況。優化
1 var ids = { 2 *[Symbol.iterator]: function () { 3 var index = 0; 4 5 return { 6 next: function () { 7 return { value: 'id-' + index++, done: false }; 8 } 9 }; 10 } 11 }; 12 13 var counter = 0; 14 15 for (var value of ids) { 16 console.log(value); 17 18 if (counter++ > 1000) { // let's make sure we get out! 19 break; 20 } 21 }
若是你還不瞭解ES6 generator
函數,請參考MDN文檔。簡而言之,generator
函數是當前被談論最多的ES6特性,它是一個能夠暫時退出,而且稍後從新進入繼續執行的函數。在屢次的進入中,它的上下文(綁定的變量)是會被保存的。generator
函數自身就是一個迭代器,來看下面的例子:this
1 function* list(value) { 2 for (var item of value) { 3 yield item; 4 } 5 } 6 7 for (var value of list([1, 2, 3])) { 8 console.log(value); 9 } 10 11 var iterator = list([1, 2, 3]); 12 13 console.log(typeof iterator.next); // function 14 console.log(typeof iterator[Symbol.iterator]); // function 15 16 console.log(iterator.next().value); // 1 17 18 for (var value of iterator) { 19 console.log(value); // 2, 3 20 }
因此,咱們可使用generator
函數重寫咱們上面的迭代器:spa
1 table[Symbol.iterator] = function* () { 2 var keys = Object.keys(this).sort(); 3 4 for (var item of keys) { 5 yield item; 6 } 7 }
迭代器給JavaScript
中的循環,generator
函數和值序列(value series)帶來了一個新的維度。你可使用它,定義一個類中,它的值的排序方式,也能夠用經過其來建立一個惰性的或無限的序列,等等。rest
https://strongloop.com/strongblog/introduction-to-es6-iterators/
譯文地址:
http://segmentfault.com/a/1190000003021261