4 / 4 聊一聊Symbol.iterator屬性

前面的話

前端每日,鞏固基礎,不打烊!!!

解答

從一道題來分析:

我們需要向對象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 ... ofGennerator函數配合使用,這樣不需要再調用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]); 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章