iT邦幫忙

2025 iThome 鐵人賽

DAY 17
0

[Symbol.iterator]

提供給for..of的物件必須有可迭代性(iterable)
物件(Object)不可迭代,僅能用特殊方法獲取可枚舉(enumerable)的屬性值

這時候可以在 Object 上增加一個特殊的屬性 [Symbol.iterator]讓 Object 可以被迭代
呼叫這個方法應回傳一個物件,用以提供第二個 interface ,也就是迭代器(iterator)

迭代器附有一個 next method,具有 value 跟 done 屬性
下一個值存在,則具有 value 且 done 為 false
沒有下個值,則不具有 value 且 done 為 true

示例如下

const myDiet = {
    meal: {
        breakfast: "apple",
        lunch: "avocado",
        dinner: ["cabbage", "carrot"],
    },
    haveMeal: function (foodName, mealName) {
        console.log(`I have ${foodName} as ${mealName}.`);
    },
    [Symbol.iterator]() {
        const nameOfMeal = Object.keys(this.meal);
        const nameOfFood = Object.values(this.meal);
        let index = 0;
        // must return an iterator object with a `next()` method
        return {
            next: () => {
                if (index < nameOfFood.length) {
                    this.haveMeal(nameOfFood[index], nameOfMeal[index]);
                    return { value: nameOfFood[index++], done: false };
                } else {
                    return { done: true };
                }
            },
       };
    },
};
      
for (const item of myDiet) {
    console.log(item);
}

已經有 Object.keys ,Object.entries 跟 for..in 那為何還要有 [Symbol.iterator]呢?

[Symbol.iterator] 並不是要用來『取代』其他物件方法
物件屬性混合了不同資料類型的話,可用 [Symbol.iterator] 來建立出乾淨且清晰的自訂迭代內部值的方法,它允許為複雜物件建立簡單且標準的迭代,向迴圈隱藏物件的內部結構

以上方例子來說,執行for loop時並不會知道 myDiet 物件 meal 屬性的內部結構,這有助於抽象化(Abstraction)與封裝(Encapsulation)


上一篇
Chapter 6 物件的秘密(Symbol)-day16
下一篇
Chapter 6 物件的秘密(matrix exercise)-day18
系列文
溫故而知新:Eloquent Javascript 閱讀筆記19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言