TOC
ECMAScript 6 简介
ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
Iterator
Iterator(遍历器)的概念
- 
基本用法: 遍历器(
Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。 - 
作用:
- 为各种数据结构,提供一个统一的、简便的访问接口
 - 使得数据结构的成员能够按某种次序排列
 - ES6 创造了一种新的遍历命令
for...of循环,Iterator接口主要供for...of消费。 
 - 
遍历过程:
- 创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
 - 调用指针对象的
next方法,可以将指针指向数据结构的下一个成员。返回一个包含value和done两个属性的对象 。其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。 - 不断调用指针对象的
next方法,直到它指向数据结构的结束位置。 
var it = makeIterator(['a', 'b']); it.next() // { value: "a", done: false } it.next() // { value: "b", done: false } it.next() // { value: undefined, done: true } function makeIterator(array) { var nextIndex = 0; return { next: function() { return nextIndex < array.length ? {value: array[nextIndex++], done: false} : {value: undefined, done: true}; } }; } ======================== interface Iterable { [Symbol.iterator]() : Iterator, } interface Iterator { next(value?: any) : IterationResult, } interface IterationResult { value: any, done: boolean, } 
默认 Iterator 接口
- 
基本用法:
Iterator接口的目的,就是为所有数据结构,提供了一种统一的访问机制,即for...of循环。当使用for…of循环遍历某种数据结构时,该循环会自动去寻找Iterator接口。ES6 规定,默认的
Iterator接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是可遍历的(iterable)。Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。至于属性名Symbol.iterator,它是一个表达式,返回Symbol对象的iterator属性,这是一个预定义好的、类型为Symbol的特殊值,所以要放在方括号内。const obj = { [Symbol.iterator] : function () { return { next: function () { return { value: 1, done: true }; } }; } }; - 
原生具备
Iterator接口的数据结构:- Array
 - Map
 - Set
 - String
 - TypedArray
 - 函数的 arguments 对象
 - NodeList 对象
 
 
for…of 循环
- 基本用法:
for...in:遍历数组的键名forEach:break或return命令无法中途跳出循环for...of: 提供了遍历所有数据结构的统一操作接口
 
Generator
Generator的概念
- 基本用法:
- 语法上: 
Generator函数是一个状态机,封装了多个内部状态。执行Generator函数会返回一个遍历器对象。 - 形式上: 
Generator函数是一个普通函数,但是有两个特征:function关键字与函数名之间有一个星号(*)- 函数体内部使用
yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”) 
 
function* helloWorldGenerator() { yield 'hello'; yield 'world'; return 'ending'; } var hw = helloWorldGenerator(); - 语法上: 
 
yield表达式
- 
基本用法: 由于
Generator函数返回的遍历器对象,只有调用next方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。yield表达式就是暂停标志,yield表达式只能用在Generator函数里面。 - 
遍历器对象的
next方法的运行逻辑:- 遇到
yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。(yield表达式本身没有返回值,或者说总是返回undefined) - 下一次调用
next方法时,再继续往下执行,直到遇到下一个yield表达式。 - 如果没有再遇到新的
yield表达式,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。 - 如果该函数没有
return语句,则返回的对象的value属性值为undefined。 
function* helloWorldGenerator() { yield 'hello'; yield 'world'; return 'ending'; } var hw = helloWorldGenerator(); - 遇到
 
next 方法的参数
- 基本用法:
yield表达式本身没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。function* helloWorldGenerator() { yield 'hello'; yield 'world'; return 'ending'; } var hw = helloWorldGenerator(); 
Generator.prototype.throw()
- 基本用法:
Generator函数返回的遍历器对象,都有一个throw方法,可以在函数体外抛出错误,然后在Generator函数体内捕获。var g = function* () { try { yield; } catch (e) { console.log('内部捕获', e); } }; var i = g(); i.next(); try { i.throw('a'); i.throw('b'); //Generator 函数内部的catch语句已经执行过了,不会再捕捉到这个错误了 } catch (e) { console.log('外部捕获', e); } // 内部捕获 a // 外部捕获 b //throw方法被捕获以后,会附带执行下一条yield表达式 var gen = function* gen(){ try { yield console.log('a'); } catch (e) { // ... } yield console.log('b'); yield console.log('c'); } var g = gen(); g.next() // a g.throw() // b g.next() // c 
Generator.prototype.return()
- 基本用法:
Generator函数返回的遍历器对象,还有一个return方法,可以返回给定的值,并且终结遍历Generator函数。function* gen() { yield 1; yield 2; yield 3; } var g = gen(); g.next() // { value: 1, done: false } g.return('foo') // { value: "foo", done: true } g.next() // { value: undefined, done: true } 
next()、throw()、return() 的共同点
- 基本用法:
next()、throw()、return()这三个方法本质上是同一件事,它们的作用都是让Generator函数恢复执行,并且使用不同的语句替换``yield表达式。 
yield* 表达式
- 基本用法:
ES6 提供了
yield*表达式,用来在一个Generator函数里面执行另一个Generator函数。function* foo() { yield 'a'; yield 'b'; } function* bar() { yield 'x'; yield* foo(); yield 'y'; } // 等同于 function* bar() { yield 'x'; yield 'a'; yield 'b'; yield 'y'; } 
作为对象属性的 Generator 函数
let obj = {
  * myGeneratorMethod() {
    ···
  }
};
等同于
let obj = {
  myGeneratorMethod: function* () {
    // ···
  }
};
Generator 函数的this
- 基本用法:
Generator函数总是返回一个遍历器,ES6 规定这个遍历器是Generator函数的实例,也继承了Generator函数的prototype对象上的方法。Generator函数也不能跟new命令一起用,会报错。function* g() {} g.prototype.hello = function () { return 'hi!'; }; let obj = g(); obj instanceof g // true obj.hello() // 'hi!' 
「下次一定」
下次一定
使用微信扫描二维码完成支付