ES6

ES6深入浅出之迭代器与生成器

Posted by weite122 on 2018-12-15

原有字面量加强

新增数据类型

  • 一个迭代器对象 ,知道如何每次访问集合中的一项, 并跟踪该序列中的当前位置。在 JavaScript 中 迭代器是一个对象,它提供了一个next() 方法,用来返回序列中的下一项。这个方法返回包含两个属性:donevalue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function 发布器(){
var _value = 0
return{b
next: function(){
_value += 1
return {
value: _value
}
}
}
}

a = 发布器()
//{next: ƒ}
a.next()
//{value: 1}



function 发布器(){
var value =0
var max = 10
return {
next: function(){
return value < max ?
{value: value++, done:false} : {done: true}
}
}
}

生成器

  • ES6提供了新的语法糖更方便的定义一个迭代器
1
2
3
4
5
6
7
8
9
10
11
12
13
function* 发布器(){
var version = 0
while(true){
version += 1
yield version;
}
}

var a = 发布器()

a.next()//{value: 1, done: false}
a.next()//{value: 1, done: false}
a.next()//{value: 1, done: false}

可迭代对象

  • 一个定义了迭代行为的对象,比如在for…of中循环了哪些值。一些内置类型,如ArrayMap具有默认的迭代行为,而其他类型(如Object)没有。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var array = [1,2,3]
var object = {a:1,b:2,c:3}

for(let key in array){
console.log(key)
}

for(let key in object){
console.log(key)
}

for(let key of array){
console.log(key)
}

for(let key of object){
console.log(key)
}//Object不能迭代,所以会报错
  • 为什么ArrayObject都能实现遍历,而Array能迭代,Object不能迭代?Array不是属于Object么?
  • 首先ArrayObject__proto__不同,其实数组和Object的key值顺序不一定是按照遍历的顺序来的,如下图。他们本质的区别就是Array__proto__指向的是Array.prototype,Object__proto__指向的是Object.prototype

深度截图_选择区域_20190120010433.png

  • 既然原型链不同,对应的属性也不会相同。一个可迭代的对象必须代有Symbol.iterator属性。

    1
    2
    3
    4
    5
    var array = [1,2,3]
    var object = {a:'x',b:'y',c:'z'}

    array[Symbol.iterator]//ƒ values() { [native code] }
    object[Symbol.iterator]//undefined
  • 现在给上面object添加Symbol.iterator属性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    object[Symbol.iterator] = function* (){
    let keys = Object.keys(object)
    for(i = 0;i < keys.length; i++){
    yield object[keys[i]]
    }
    }
    for(let key of object){
    console.log(key)
    }// x y z