程式開發指的疊代與迭代?
「疊代」:累進取代,不斷重複進行後者加上前者、替換掉前者的動作;
「迭代」:替換取代,表示幾個固定的物件彼此輪替取代的動作。
正體中文於程式上線更新講的
「疊代」表示更新數字有向上、程式開發有進展。
「迭代」,表示程式只有在幾個版本中彼此輪流替換,最糟糕的情況是進版又退版、進版又退版的二元交替。
資料出處:
請問到底是在「疊代」或是在「迭代」?
JavaScript 的疊代
陣列可疊代與物件不可疊代的差別
哪些可以疊代?
Array、 Array-like Object (類陣列)、 Set、 Map、 String,可使用 for in 迴圈方法進行疊代。
物件與陣列的疊代,物件資料無法以 [Symbol.iterator] 進行疊代,同樣是物件原始型別,但確有著差異。
1 2 3 4 5 6 7 8 9 | let obj = { name: 'wendy', age: 18, [Symbol.iterator]: '勵志成為迭代物件', }; for (let x of obj) { console.log(x); } //TypeError: obj is not iterable |
1 2 3 4 5 6 7 | let myArray = ['wendy', 20, 30]; for (let x of myArray) { console.log(x); } //wendy //20 //30 |
疊代操作
注意單字字根的 ble tor tion 的差別,一點點的差就差很多。
iterable object (可疊代物件)
String、Array、Set、Map、arguments 對象、NodeList 集合 (可疊代的型別)
iterator object (疊代器物件)
自己本身可以疊代
iteration object (疊代結果物件)
存放疊代每步驟的結果
iterable object (可疊代物件)
Symbol.iterator 的屬性,會回傳疊代器物件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /* String */ let myStriing = 'myString'; let myStriingIterator = myStriing[Symbol.iterator](); // String Iterator { } /* Array */ let myArray = [10, 20]; // 可疊代物件 let myArrayIterator = myArray[Symbol.iterator](); console.log(myArrayIterator); // Array Iterator { } /* Set */ let mySet = new Set([1, 2]); // 可疊代物件 console.log(mySet[Symbol.iterator]()); // Set Iterator { } /* Map */ let myMap = new Map([ [1, 'wendy'], [2, 'nick'], ['red', 'apple'], ]); console.log(myMap[Symbol.iterator]()); // Map Iterator { } /* 使用不可疊代物件 */ let myNumber = 10; console.log(myNumber[Symbol.iterator]); //undefined let myObj = { 1: 'wendy', 2: 'ann' }; console.log(myObj[Symbol.iterator]); //undefined |
疊代器物件 iterator object
Array Iterator、Set Iterator、Map Iterator 是由相關的建構函式所建立的 Iterator 疊代器物件物件,在 Iterator 之中的原型下都會有 next() 的函式方法。
疊代結果物件 iteration object
物件裡具有 value 和 done 的屬性。
Symbol.iterator 就是裡面內的 Symbol,對於可疊代的型別,在 Symbol.iterator 中就有提供函式可以讓它在 for...of 時使用。
1 2 3 4 5 6 7 8 | let arr = [1, 2, 3]; console.log(typeof arr[Symbol.iterator]); // function let current = arr[Symbol.iterator](); current.next(); // Object {value: 1, done: false} current.next(); // Object {value: 2, done: false} current.next(); // Object {value: 3, done: false} current.next(); // Object {value: undefined, done: true} |
疊代器可以透過 next(),一直產生出序列值。
客制化 iterator
在一般物件無法疊代
1 2 3 4 5 6 7 8 9 | let obj = { name: 'wendy', age: 18, goal: '勵志成為迭代物件', }; for (let x of obj) { console.log(x); } // TypeError: obj is not iterable |
一般物件下自製疊代器,條件如下
– for...of 遂一執行每一筆資料時,在當 Iterator 的 done 為 true 時就不再疊代。
– 要有 next()
– 一般物件下 [Symbol.iterator]: 所賦予的函式,在回傳的部份是一個物件其中帶著 next 屬性,將當筆資料做為回傳出來的內容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | let person = { firstName: 'Aaron', lastName: 'Chen', hobbies: ['computer', 'programming', 'sports'], // 讓 JS 知道這個物件具有 iterator,所以是 iterable [Symbol.iterator]: function () { let index = 0; let hobbies = this.hobbies; return { next() { return index < hobbies.length ? { done: false, value: hobbies[index++], } : { done: true, value: undefined, }; }, }; }, }; for (let hobby of person) { console.log(hobby); // computer, programming, spots } |
參考資料
初學者跪著學JavaScript Day28 : 學迭代,學習不等待
pjchender – [JS] JavaScript 疊代器(Iterator)
MDN – 迭代協議