ES6详解七:循环的秘密 - iterator 和 yield

如果学过设计模式或者java之类的肯定知道 iterator 是什么,在 Symbol.iterator 出现后,JS中也可以自己定义一个迭代器。
只要一个对象实现了正确的 Symbol.iterator 方法,那么它就可以被 for in 所遍历,如下所示:

var students = {}

students[Symbol.iterator] = function() {
  let index = 1;
  return {
    next() {
      return {done: index>100, value: index++}
    }
  }
}

for(var i of students) {
  console.log(i);
}

仔细看上面的代码就会明白迭代器是如何工作的。当执行 for(var i of students) 的时候,其实是调用了 students[Symbol.iterator]() 方法,这个方法返回了一个iterator(迭代器)。迭代器有一个next方法,for循环会不断调用这个 iterator.next方法来获取下一个值,直到返回值中的 done 属性为true的时候结束循环。

那么知道原理之后,我们可以自己来调用iterator.next来实现循环:

var students = {}

students[Symbol.iterator] = function() {
  let index = 1;
  return {
    next() {
      return {done: index>100, value: index++}
    }
  }
}

var iterator = students[Symbol.iterator]();

var s=iterator.next();
while(!s.done) {
  console.log(s.value);
  s=iterator.next();
}

上例中使用 iterator.next 和 while 结合实现了 for循环。

除了使用iterator 之外,我们还可以使用 yield 语法来实现循环,yield相对简单一些,只要通过 yield 语句把值返回即可:

let students = {
  [Symbol.iterator]: function*() {
    for(var i=0;i<=100;i++) {
      yield i;
    }
  }
}

for(var s of students) {
  console.log(s);
}

看到这里可能大家会怀疑 yield 和 iterator 到底是什么关系。这个我还不能确定,不过从用法上来说,可以基本认为 yield 只是 iterator 的语法糖,它其实就是最终生成了一个 iterator
,下面我们通过取出 yield 生成的 iterator 就可以看出来:

let students = {
  [Symbol.iterator]: function*() {
    for(var i=0;i<=100;i++) {
      yield i;
    }
  }
}
var iterator = students[Symbol.iterator]();
var s=iterator.next();
while(!s.done) {
  console.log(s.value);
  s=iterator.next();
}

如上代码所示, yield 语句其实就是生成了一个 iterator ,完全和直接写 iterator 没区别,不过好处是使代码变得简洁明了,因此建议直接使用 yield 语法而不要费力的去写 iterator。

看完 上面的iterator 和 yield语法,其实看似神秘的循环也就很容易理解了。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值