前面的话
前端每日,巩固基础,不打烊!!!
解答
从一道题来分析:
我们需要向对象person添加什么,以致执行[…person]时,获得形如[‘xiaoq’,20]的输出。
const person = {
name: 'xiaoqi',
age: 20
}
// [...person]; ? // ['xiaoqi',20]
分析
- 对象默认不是可迭代的,如果通过[Symbol.iterator]来定义迭代规则,那么对象就是可迭代的。
- 只有可迭代的对象,才能使用[…person]变成数组,ES6中的数组、Set/Map、字符串都有默认的迭代器和Symbol.iterator属性。
- 通过生成器Generator返回的迭代器也是可迭代的对象,因为生产器默认会为Symbol.iterator属性赋值
- 注意:弱引用集合WeakSet与WeakMap集合是不可迭代的。
Symbol.iterator
可迭代对象的Symbol.iterator属性是一个函数:
let list = [11, 22, 33];
let iterator = list[Symbol.iterator]();
console.log(iterator.next()); // {value: 11, done: false}
创建可迭代对象
let test = {
items: [11,22, 33],
*[Symbol.iterator]() {
for(let item of this.items){
yield item;
}
}
}
for(let item of test) {
console.log(item);
}
for ... of
与Gennerator
函数配合使用,这样不需要再调用next方法。
- Iterator接口主要供for…of消费,for…of循环会自动寻找Iterator接口,默认的Iterator接口部署在数据结构的Symbol.iterator属性,数据结构只要具有Symbol.iterator属性,就一个使用for…of或者…扩展运算符。
- 类数组:DOM Nodelist, arguments等对象都可以使用for…of与扩展运算符。
回到本题
person不是可迭代对象,使用Symbol.iterator使之成为可遍历的:
const person = {
name: 'xiaoqi',
age: 20,
*[Symbol.iterator]() {
yield this.name;
yield this.age;
}
}
console.log( [...person]);