> 文章列表 > ES6()

ES6()

ES6()

一、Iterator和for...of循环

1.Iterator遍历

  • 一是为各种数据结构,提供一个统一的、简便的访问接口
  • 二是使得数据结构的成员能够按某种次序排列
  • Iterator 接口主要供for...of消费

目前知道四种数据集合(Array、Object、Map、Set)

使用方式:

(1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。

(2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。

(3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。

(4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。

返回value(成员值)和done(布尔值:表示遍历是否结束)

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};//两个属性都是可以省略}};
}

 没有对应的数据结构,遍历器对象会自己描述了一个数据结构出来

var it = idMaker();//这里没有数据结构it.next().value // 0
it.next().value // 1
it.next().value // 2
// ...function idMaker() {var index = 0;return {next: function() {return {value: index++, done: false};}};
}

 2. 默认接口

ES6 规定,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”

const obj = {[Symbol.iterator] : function () {return {next: function () {return {value: 1,done: true};}};}
};

原生具备 Iterator 接口的数据结构如下 :

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象

3. for...of循环

个数据结构只要部署了Symbol.iterator属性,就被视为具有 iterator 接口,就可以用for...of循环遍历它的成员。也就是说,for...of循环内部调用的是数据结构的Symbol.iterator方法

替代forEach方法

 使用范围:

Set 和 Map 结构、某些类似数组的对象(比如arguments对象、DOM NodeList 对象)、 Generator 对象,以及字符串

数组:

  • for...in循环读取键名(下标)
  • for...of循环读取键值
  • 可以借助数组实例的entries方法和keys方法
const arr = ['red', 'green', 'blue'];for(let v of arr) {console.log(v); // red green blue
}const obj = {};
obj[Symbol.iterator] = arr[Symbol.iterator].bind(arr);for(let v of obj) {console.log(v); // red green blue
}

Set和Map 

ar engines = new Set(["Gecko", "Trident", "Webkit", "Webkit"]);
for (var e of engines) {console.log(e);
}
// Gecko
// Trident
// Webkitvar es6 = new Map();
es6.set("edition", 6);
es6.set("committee", "TC39");
es6.set("standard", "ECMA-262");
for (var [name, value] of es6) {console.log(name + ": " + value);
}
// edition: 6
// committee: TC39
// standard: ECMA-262

类数组对象和字符串

// 字符串
let str = "hello";for (let s of str) {console.log(s); // h e l l o
}// DOM NodeList对象
let paras = document.querySelectorAll("p");for (let p of paras) {p.classList.add("test");
}// arguments对象
function printArgs() {for (let x of arguments) {console.log(x);}
}
printArgs('a', 'b');
// 'a'
// 'b'

 对象:不可以直接使用for...of(需要遍历器接口),可以直接使用for...in

let es6 = {edition: 6,committee: "TC39",standard: "ECMA-262"
};for (let e in es6) {console.log(e);
}
// edition
// committee
// standardfor (let e of es6) {console.log(e);
}
// TypeError: es6[Symbol.iterator] is not a function//--------------------------------------------
解决方法:将对象转为数组
for (var key of Object.keys(someObject)) {console.log(key + ': ' + someObject[key]);
}

二、 Generator 函数

1.Generator函数的说明与使用

Generator 函数是一个状态机,封装了多个内部状态;

执行 Generator 函数会返回一个遍历器对象

 Generator 函数是一个普通函数,

  • function关键字与函数名之间有一个星号
  • 函数体内部使用yield表达式
    function* helloWorldGenerator() {yield 'hello';yield 'world';return 'ending';
    }var hw = helloWorldGenerator();

 Generator函数就算使用函数调用方式不会直接执行,需要next方法:每次调用时候调用一次方法

yield表达式是暂停执行的标记,而next方法可以恢复执行

hw.next()
// { value: 'hello', done: false }hw.next()
// { value: 'world', done: false }hw.next()
// { value: 'ending', done: true }hw.next()
// { value: undefined, done: true }

 2.yield表达式

  • 遇到yield表达式,就暂停执行后面的操作
  • 下一次调用next方法时,再继续往下执行
  • 如果没有再遇到新的yield表达式,就一直运行到函数结束,直到return语句为止
  • 如果该函数没有return语句,则返回的对象的value属性值为undefined

 3. 场景:为了不具备Interator接口的对象提供遍历操作

      const obj = {name: "haha",age: 18,};obj[Symbol.iterator] = objectEntries; //生成器function* objectEntries(obj) {// 获取对象那个的所有的key// 保存到数组中const propKeys = Object.keys(obj); //获取对象中的所有keyfor (const propkey of propKeys) {// 生成器键值对yield [propkey, obj[propkey]];}}console.log(obj);//生成器生成之后for (let [key, value] of objectEntries(obj)) {console.log(`${key},${value} `);}