es6 迭代器 和 生成器 学习笔记

1. 迭代器 iterator

数组、Set、Map、NodeList对象可以使用for-of循环,因为有默认的迭代器属性。对象没有默认的迭代器。

可以使用Symbol.iterator来定义迭代器。

迭代器的出现背景:虽然循环语句简单,但是如果将多个循环嵌套则需要追踪多个变量,代码的复杂度会大大增加,一不小心就错误的使用了其他for循环的跟踪变量,从而导致程序出错,迭代器的出现旨在消除这种复杂性并减少循环中的错误。

迭代器是一种特殊的对象,每个迭代器对象都有一个next()方法,每次调用这个方法都会返回一个对象,这个对象包括两个属性:value,表示下一个将要返回的值,done:布尔值,当没有更多可返回的数据时返回true,并且后面都会返回true

2. 生成器 generator

生成器是一种返回迭代器的函数,函数中会用到新的关键字yield。格式如下

function *fname(){

  yield 1;

  yield 2;

}

let iterator = fname();

console.log(iterator.next().value);   //1

生成器最有趣的地方是,每执行一条yield语句后函数就会自动停止执行,直到再次调用迭代器的next()方法才会继续执行。

yield的使用限制: yield关键字只可在生成器内部使用,在其他地方使用会导致程序抛出语法错误

function *createIterator(items){

  items.forEach(function(item){

    //语法错误

    yield item+1;

  })

}

它与return一样不能穿透函数边界

也可以通过函数表达式定义生成器

var createIterator = function *(){

  ..

  yield 1;

}

还可以在对象里定义生成器

let o = {

  createIterator: function *(){

    yield 1;

  }

}

let o = {

  *createIterator(){

    yield 1;

  }

}

注意: 不能用箭头函数来创建生成器。为什么?箭头函数和普通的函数有哪些不同:

首先没有this、arguments、super和new.target绑定,这些值由外围最近一层非箭头函数决定。

不能通过new关键字调用,箭头函数没有construct方法

没有原型,不存在prototype这个属性

不可以改变this的绑定,函数内部的this值不可以改变(因为是外部的this),在函数的生命周期内始终保持一致。

3. 可迭代对象和for-of循环

可迭代对象具有Symbol.iterator属性,是一种与迭代器密切相关的对象

Symbol.iterator通过制定的函数可以返回一个作用于附属对象的迭代器:

let values = [1,2,3];

let iterator = values[Symbol.iterator]();

console.log(iterator.next());

在ES6中,所有的集合对象(数组、Set集合、Map集合)和字符串都是可迭代对象。for-of需要用到可迭代对象的这些功能。

for-of循环每次执行都会调用可迭代对象的next()方法,并将迭代器返回的结果对象的value属性存储在一个变量中,循环将持续执行这一过程直到返回对象的done属性的值为true。

将for-of循环用于不可迭代对象、null或undefined将会导致程序抛出错误。

猜你喜欢

转载自www.cnblogs.com/wenwenli/p/8276567.html