如何优雅迭代JS字面对象?
站长
· 阅读数 15
大家好,我是速冻鱼🐟,一条水系前端💦,喜欢花里胡哨💐,持续沙雕🌲,是隔壁寒草🌿的好兄弟。 欢迎小伙伴们加我微信:
sudongyuer
拉你进群,一起讨论,期待与大家共同成长🥂。
文末有鱼鱼对JavaScript对象深度的理解
为什么要实现自定义迭代器
因为在JavaScript
中字面量对象
是不支持迭代
的
如何实现JavaScript字面量对象迭代
- 只要正确实现字面对象的
Symbol.iterator
这个属性所对应的迭代器函数
即可 - 注意⚠️该
迭代器函数
只是一个函数
,而不是真正的迭代器
迭代器
是一个对象
,需要提供next
函数来提供给类似for of
forEach
这种迭代函数
使用
实现方法
第一种使用比较简单的遍历来实现
let obj = {uname: "zhangsan"};
obj[Symbol.iterator] = function () {
const keys = Object.keys(this);
let index = 0;
return {
next() {
return {
value: obj[keys[index++]],
done: index > keys.length
}
}
};
};
let iterator = obj[Symbol.iterator]();
console.log(iterator.next());
//{value: 'zhangsan', done: false}
obj.uname='sudongyu'
iterator = obj[Symbol.iterator]();
console.log(iterator.next());
//{value: 'sudongyu', done: false}
第二种使用
生成器函数
来实现
/**
* 将{}对象转换为可迭代对象
*/
function object2iterator(obj){
obj[Symbol.iterator]=function* () {
let properties = Object.keys(this);
for (let i of properties) {
yield [i, this[i]];
}
}
return obj
}
生成器详细API 请参考 mdn
解析为什么生成器函数要这样设计
以下纯个人理解,如果有歧义就当我放屁~ 哈哈哈
迭代器函数
是一个函数,这样每次调用都会为将要return
的迭代器
中的next
函数创建一个全新的词法作用域
- 这样每次在创建新的迭代器时,执行
iterator.next()
的时候就可以利用闭包
访问到属于自己的外层词法环境
中的变量
,在方法一中
也就是能够从index
为0
开始迭代 - 这样每个独立的
迭代器对象
就能相互隔离~
注意⚠️:我还想表达以下几个观点:
JavaScript
中的对象只是数据的载体
,集合
- 所以我们不能把
对象
中的函数
或者属性
作为对象的一部分
对象
的属性
和函数
它们只是一个间接
的关系,虽然有点难理解,但是我还是想表达一下这个观点- 打个比方来讲,
你(对象)
身上的钱(属性或者对象上的函数)
只是你作为了它暂时的载体
,并不意味着这个钱就属于
你身体的一部分