# 可迭代协议
可迭代协议
- 可迭代协议规定了【for...of】迭代的条件是自身或原型链上有[Symbol.iterator]方法
const arr = [1, 2, 3];
console.log(arr[Symbol.iterator]); // [Function: values]
console.log(arr[Symbol.iterator]()); // Object [Array Iterator] {}
const obj = {};
console.log(obj[Symbol.iterator]); // undefined
1
2
3
4
5
6
2
3
4
5
6
# 迭代器协议
迭代器协议
- 迭代器协议规定迭代器函数必须返回一个生成器对象:包含【function next()】的【对象】
- next() 返回一个指定属性的对象: {done: bool, value: any}
- 首次执行next()的时候才开始进入执行函数,因此首次next入参无效
- 后续的next会作为yield表达式的值传入
const arr = [1, 2, 3];
console.log(arr[Symbol.iterator]().next()); // { value: 1, done: false }
1
2
3
2
3
- Object不是可迭代对象,改写成可迭代对象(按照可迭代协议给对象增加迭代器)
遍历自身所有可枚举属性
const obj = {
name: 'hdy',
age: 18,
[Symbol.iterator]() {
let vals = Object.values(this);
let idx = 0;
return {
next:() => idx < vals.length ? {value: vals[idx++], done: false} : {value: undefined, done: true}
}
}
};
for (let value of obj) {
console.log(value); // hdy 18
}
for (let value of obj) {
console.log(value); // hdy 18
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
利用
生成器
函数
const obj = {
name: 'hdy',
age: 18,
*[Symbol.iterator]() {
const vals = Object.values(this);
for (let val of vals) {
yield val;
}
}
}
for (let value of obj) {
console.log(value);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# function*
function*
- 作用:声明一个生成器函数,
- 返回:返回可迭代对象【generator】【生成器】
# yield
# 生成器
生成器
- 生成器对象由generator 【function*】返回,符合可迭代协议和迭代协议。
- 有以下原型方法:
- next
- return
- throw
- 时间生成器:每次执行都生成当前的时间
function* generator() {
while(true) {
yield new Date().toLocaleString()
}
}
// generator返回的 生成器gen
const gen = generator();
console.log(gen.next().value);
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# next
- 作用:调用生成器的下一个值,并且可以传值
- 调用:generator.next(any)
- 入参:any
- 返回:{done: bool, value: any}
入参
- 第一次调用next的入参无效
# return
return
- 作用:返回给定值并结束生成器
- 调用:generator.return(value)
- 入参:any
- 返回:{done: true, value: any}
# throw
- 作用:向生成器抛出异常
- 调用:generator.throw(new Error(tip))
- 入参:Error
- 返回:{value: any, done: bool}
function* generator() {
let value = 1;
while(true) {
try {
value = yield value;
} catch(e) {
console.log(e); // Error: 自定义错误
}
}
}
const gen = generator();
console.log(gen.next().value); // 1
console.log(gen.throw(new Error('自定义错误'))); // { value: 1, done: false }
console.log(gen.next()); // { value: undefined, done: false }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17