方法一:自定義Symbol.iterator屬性
如果對象擁有[Symbol.iterator]
?方法,改方法返回一個迭代器對象,就可以稱之為可迭代對象,注意迭代器是一個有 next 方法的對象
?步驟如下
- 實現一個Symbol.iterator 鍵
- 值是一個函數,函數返回一個迭代器
- 迭代器是一個對象,對象里有一個next方法
- next 方法按照條件返回 {value, done} 的對象
const obj = {name: 'name value',age: 'age value'
}
// 實現一個Symbol.iterator 鍵
// 值是一個函數,函數返回一個迭代器
// 迭代器是一個對象,對象里有一個next方法
// next 方法按照條件返回 {value, done} 的對象
obj[Symbol.iterator] = function () {const keys = Object.keys(this)let index = 0return {// 一定要使用箭頭函數,要不下面的this 不對next: ()=> {if (index < keys.length) {return {// index++ 使用,這條語句結束后再 +1value: this[keys[index++]],done: false}}return {done: true}}}
}
for (let i of obj) {console.log(i) // 這個打印的是 value的值 ,name value, age value
}
// 顯式調用
console.log(obj[Symbol.iterator]().next().value)
方法二:使用生成器
生成器真好用
const obj = {name: 'name value',age: 'age value'
}
// function 和函數名之間加一個星號就是一個生成器函數
function* toIterator(obj) {let keys = Object.keys(obj)for (let key of keys) {// 原理是生成器中// 每調用一次遇到 yield 都會停止,并返回【迭代器對象的狀態】// 【迭代器對象的狀態】是一個對象,{ value:'xx', done: true/false }// 并將 yield 后面的那個【表達式的值】,作為返回的對象的 value 屬性值// 如果沒有 yield 就會一直運行到函數結束,直到 return 語句// 并將 return 語句后面的表達式值,作為 value// 如果沒有 return 語句,則返回的 value 為 undefinedyield obj[key] // 可以自定義遍歷的值,這里是 obj 的 value}
}
// 變成可迭代對象
const newObj = toIterator(obj)
// 使用 for of 遍歷
for (let i of newObj) {console.log(i) // name value , age value
}