一日客語:中文:報紙 客語:bo ziiˋ
最近很疑惑迭代物件和可迭代到底是什麼??於是查一下資料,發現很有趣
Array、Set、Map、String
能使用for/of迴圈來迭代
不可以迭代
let obj = {
name: 'wendy',
age: 18,
[Symbol.iterator]: '勵志成為迭代物件',
};
for (let x of obj) {
console.log(x);
}
//TypeError: obj is not iterable
可以迭代
let myArray = ['wendy', 20, 30];
for (let x of myArray) {
console.log(x);
}
//wendy
//20
//30
會什麼會這樣呢?明明都是物件居然搞差別待遇!!!
先說說概念
圖例說明:
iterable object 可迭代物件: Array、 Set、 Map (可迭代的型別)
iterator object 迭代器物件 (自己本身可以迭代)
iteration object 迭代結果物件 (存放迭代每步驟的結果
不管是中文還是英文,名字長超像一開始很容易搞混!!
具有 Symbol.iterator 的屬性,會回傳迭代器物件
可以使用 for/of 來迭代
能使用 spread 展開運算子
能使用解構賦值( Destructuring assignment )
let myArray = [10, 20];//可迭代物件
let myArrayIterator = myArray[Symbol.iterator]();
console.log(myArrayIterator);
//Object [Array Iterator] {}
let mySet = new Set([1, 2]);//可迭代物件
console.log(mySet[Symbol.iterator]());
//[Set Iterator] { 1, 2 }
let myMap = new Map([
[1, 'wendy'],
[2, 'nick'],
['red', 'apple'],
]);
console.log(myMap[Symbol.iterator]());
//[Map Entries] { [ 1, 'wendy' ], [ 2, 'nick' ], [ 'red', 'apple' ] }
//使用不可迭代物件
let myNumber = 10;
console.log(myNumber[Symbol.iterator]); //undefined
let myObj = { 1: 'wendy', 2: 'ann' };
console.log(myObj[Symbol.iterator]); //undefined
具有 next()方法的物件,使用此 methods 會回傳迭代器結果物件
執行可迭代物件的 [Symbol.iterator] 的function
myArray[Symbol.iterator]()
回傳是一個迭代器 (iterator object) Array Iterator
怎麼知道他是迭代器物件? 因為他有 next()!!!!
物件裡具有 value 和 done 的屬性
所以輸入myArray[Symbol.iterator]().next()
會出現
{
value:xxx,
done:false
}
let myArray = [10, 20];
let myIterator = myArray[Symbol.iterator]();
console.log(myIterator.next());//{ value: 10, done: false }
console.log(myIterator.next());//{ value: 20, done: false }
console.log(myIterator.next());//{ value: undefined, done: true }
迭代器可以透過 next(),一直產生出序列值
圖片出處:A Simple Guide to ES6 Iterators in JavaScript with Examples
可迭代物件要有 [Symbol.iterator] 屬性,就可以使用 for / in 製作
一般物件無法迭代,直接報錯了
let obj = {
name: 'wendy',
age: 18,
goal: '勵志成為迭代物件',
};
for (let x of obj) {
console.log(x);
}
//TypeError: obj is not iterable
想成為迭代器嗎?
物件自己加一個 [Symbol.iterator] 屬性然後根據前面講述,把要求的條件加入
1.要有 next()
2.要有一個物件 {next:xxx,done:true/false}
let myObj = {
name: 'wendy',
age: 18,
hair: 'black',
[Symbol.iterator]: function () {
let index = 0;
let values = Object.values(this);
return {
next: () => ({ value: values[index++],
done: index > values.length }),
};
},
};
let iterator = myObj[Symbol.iterator]();
console.log(iterator.next());//{ value: 'wendy', done: false }
console.log(iterator.next());//{ value: 18, done: false }
console.log(iterator.next());//{ value: 'black', done: false }
console.log(iterator.next());//{ value: undefined, done: true }
for (let y of myObj) {
console.log(y);
}
//wendy
//18
//black
就可以做出自製迭代器, wow 是不是很棒啊,雖然有點廢,用 Object.values 就可以
但還是很開心做出來~
是根據這篇大大自制迭代物件,來改寫
所以要做出可迭代物件就要手刻,但在ES6出現新語法生成器 (generator) 新定義的迭代器
function* animal() {
yield 100;
yield 200;
yield 'wendy';
}
let genAnimal = animal();
console.log(genAnimal.next().value); //100
console.log(genAnimal.next().value); //200
console.log(genAnimal.next().value); //wendy
console.log(genAnimal.next().value); //undefined
for (x in genAnimal) {
console.log(x);
}
//100
//200
//wendy
//undefined
初學者跪著學JavaScript Day26:認識生成器,chris不生氣
讀完之後發現原來常用迭代方式背後原理是這樣
鐵人賽剩兩天~撒花
資料參考:
Make your objects iterable
JavaScript大全第七版
mdn
A Simple Guide to ES6 Iterators in JavaScript with Examples
謝謝array同學