JavaScript ES6迭代器指南

 

惰性執行

迭代器容許咱們在第一次調用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-offor-in的差異segmentfault

理解for-offor-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循環僅打印出了數組中的值,忽略了其餘屬性。這是由於數組的迭代器只返回其中預期的元素。函數

內置迭代器

StringArrayTypedArrayMapSet都是內置迭代器,由於它們的原型中都有一個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 }

 

Generator函數

若是你還不瞭解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

相關文章
相關標籤/搜索