zoukankan      html  css  js  c++  java
  • JavaScript ES6迭代器指南

    惰性执行

    迭代器允许我们在第一次调用next()函数之后,再执行相应的逻辑。在上面的例子里,当我们调用迭代器的瞬间,我们就立刻执行了排序和取值的工作。但是,如果next()函数永远不被调用的话,我们就浪费了性能。所以让我们来优化它:

     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的差别

    理解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方法。

    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函数自身就是一个迭代器,来看下面的例子:

     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函数重写我们上面的迭代器:

    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)带来了一个新的维度。你可以使用它,定义一个类中,它的值的排序方式,也可以用通过其来创建一个惰性的或无限的序列,等等。

    原文地址

    https://strongloop.com/strongblog/introduction-to-es6-iterators/

    译文地址:

    http://segmentfault.com/a/1190000003021261

  • 相关阅读:
    PAT (Advanced Level) Practice 1054 The Dominant Color (20 分)
    PAT (Advanced Level) Practice 1005 Spell It Right (20 分) (switch)
    PAT (Advanced Level) Practice 1006 Sign In and Sign Out (25 分) (排序)
    hdu 5114 Collision
    hdu4365 Palindrome graph
    单链表查找最大值、两个递增的链表合并并且去重
    蓝桥杯-最短路 (SPFA算法学习)
    蓝桥杯-最大最小公倍数
    Codeforces-470 div2 C题
    蓝桥杯-地宫取宝
  • 原文地址:https://www.cnblogs.com/pm-dongjian/p/5020079.html
Copyright © 2011-2022 走看看