iterator(迭代器)
含义:使用户在容器对象上遍访的对象,使用该接口无需关心对象的内部细节。
迭代器在JavaScript中的标准:
- 包含一个next方法
- next方法的可以有0个或1个参数
- 返回的对象应当包含done,value
- done(boolean)为false的时候表示这个对象还没有迭代完,为true表示该对象已经迭代完了
- value表示当前需要迭代的对象,迭代结束之后返回默认值undefined。
数组迭代器:
1 | const names = ['abc', 'cba', 'nba'] |
可迭代对象
可迭代对象:
- 必须实现一个特定的函数: [Symbol.iterator]
- 这个函数需要返回一个迭代器(这个迭代器用于迭代当前的的对象)
1 | const info = { |
for-of的本质就是拿到这个可迭代对象调用其中的[Symbol.iterator]()
,知道done为true时结束。
可迭代对象迭代键值对的对象
1 | const info = { |
generator(生成器)
生成器也是一个特殊的迭代器。
生成器函数的特点:
- function后面会跟上一个符号: * (*号可以在function后面function* foo(),也可以在函数名前面
function *foo()
,通常会跟在function,看个人习惯吧。) - 代码的执行可以被yield控制。(yield的作用在函数开始到yield的后面的代码,yield前面的代码时不执行的)
- 生成器函数默认在执行的时候会返回一个生成器对象
- 要想执行生成器函数内部的代码,需要执行生成器对象的next方法
- 当遇到yield就会终端执行。
1 | function* foo(num) { |
进阶用法
1 | function* foo(num) { |
return提前结束。
1 | generator.return('aaa')// 可以传递参数,但是在yield哪一行就是结束了,下面的代码不会执行。 |
throw new Error()结束。
1 | generator.throw(new Error('抛出异常结束')) |
生成器代替迭代器
第一个例子
1
2
3
4
5
6
7
8
9const names = ['abc', 'cba', 'nba']
function* createArrayGenerator(arr) {
yield* arr
}
const namesGenerator = createArrayGenerator(names)
console.log(namesGenerator.next())
console.log(namesGenerator.next())
console.log(namesGenerator.next())
console.log(namesGenerator.next())yield替换类中的实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25class Person {
constructor(name, age, height, friends) {
this.name = name
this.age = age
this.height = height
this.friends = friends
}
*[Symbol.iterator]() {
yield* Object.values(this)
// yield* Object.keys(this)
// yield* Object.entries(this)
// yield* this.friends
}
}
const p = new Person('beichen', 22, 1.76, ['beichen', 'mygirl-haixia', 'xiaoqiang'])
for (const item of p) {
console.log(item)
}
const pItem = p[Symbol.iterator]()
console.log(pItem.next())
console.log(pItem.next())
console.log(pItem.next())
console.log(pItem.next())