使用for-of循环对象

在对象和数组进行循环遍历时,我们通常会使用for-infor-of,众所周知,for-of是无法遍历对象的

COPY
1
2
3
4
5
6
let obj = {a:1, b:2, c:3};
for(let i of obj){
console.log(i)
}

// Uncaught TypeError: obj is not iterable

因为对象内部是没有迭代器对象(iterator)的,那么我们是否手动让对象实现可迭代呢?

ES6 规定,默认的 Iterator 接口部署在数据结构的 Symbol.iterator 属性,或者说,一个数据结构只要具有 Symbol.iterator 属性,就可以认为是”可遍历的”(iterable)

我们通过对对象设置原型属性来实现

COPY
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
Object.prototype[Symbol.iterator] = function(){
// 重要
let self = this
let i = 0;
let keys = Object.keys(this)
return {
// 每次遍历时,调用next(),并返回一个对象
next: function() {
let done = i >= keys.length;
let value = !done ? self[keys[i++]] : undefined;
// 该对象内包含两个值
// done 表示是否遍历是否完成
// value 表示当前值
return {
done: done,
value: value
};
}
}
}

var obj2 = {a:1,b:2,c:3}
for(let i of obj2){
console.log(i)
}

// 1 2 3

可以看出每次迭代,其实就是在调用迭代器的 next() 方法。其中 done 表示遍历是否完成,那么我们就可以通过改变done的状态来结束遍历。
比如:

COPY
1
2
3
4
5
6
7
8
9
... ...
next: function() {
// 手动控制 只遍历两次
let done = i >= 2;
// 直接结束遍历
let done = true;
... ...
}
... ...
作者: 果汁
文章链接: https://guozhigq.github.io/post/d721cd2a.html
版权声明: All posts on this blog are licensed under the CC BY-NC-SA 4.0 license unless otherwise stated. Please cite 果汁来一杯 !