前面的話
前端每日,鞏固基礎,不打烊!!!
解答
從一道題來分析:
我們需要向對象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]);