## `for`與`forEach` ### 概述 * 兩者皆可遍歷元素,常用於從陣列逐一取值的情況 ### 關於`forEach` * 操作陣列的方法 ### syntax * `forEach(callbackFn)` * 參數除了`callback function (element, index, array)`,另有`thisArg`(optional) * 無回傳值(`undefined`) * `callback`函式對原陣列的影響:遵循**傳值傳址原則** * 當陣列元素為原始型別:`By Value`不改變原陣列 ```javascript let array = [1, 3, 5]; array.forEach (function (num) { num *= num console.log (num); // 1, 9, 25 }) console.log (array); // [1, 3, 5] ``` * 當陣列元素為物件型別時`By Sharing` * 改變物件的內容:`By Reference`改變原陣列 ```javascript let array = [ { name: 'Jon', age: 23} ]; array.forEach (function (person) { // 改變物件的內容 person.age += 1; person.sex = 'male'; console.log (person); // { name: "Jon", age: 24, sex: "male" } }) console.log (array); // { name: "Jon", age: 24, sex: "male" } ``` * 重新賦值:`By Value`不改變原陣列 ```javascript let array = [ { name: 'Jon', age: 23} ]; array.forEach (function (person) { if (true) { person = [ { name: 'Jon', sex: 'male', age: 23} ]; } console.log (person); // { name: "Jon", sex: "male", age: 23 } }) console.log (array); // { name: "Jon", age: 23 } ``` ### 兩者的差異 1. 使用時機 * `forEach`屬於陣列方法,**但不適用於類陣列物件`arguments`** * `for`迴圈為通用的方法,任何可迭代物件的都可使用 2. 可讀性 * 使用`forEach`時程式碼更簡潔易讀,特別是操作陣列的情況 * `for`迴圈的可讀性不如`forEach`,但在邏輯撰寫的使用上更加靈活 3. 繼續與中斷 * `forEach`會遍歷陣列中的所有元素,無法提前結束或跳過 * `for`迴圈可利用`break`、`continue`來操縱程式碼的執行 ### 補充資料:`for...in`、`for...of` * 利用`for...in`或`for...of`處理物件時,`for...in`遍歷的對象為**鍵值(key)**,`for...of`遍歷的對象為**元素值(value)** ::: warning 💡注意:在`for...in`遍歷**陣列**的情況中,key為陣列的**索引值**,其型別為`string` ::: ```javascript let array = [1, 3, 5]; for (let num in array) { console.log (num); // keys(string): "0", "1", "2" } for (let num of array) { console.log (num); // 1, 3, 5 } ``` ### 參考文章 * [Loops and iteration - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration#for_statement) * [Array.prototype.forEach() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) ## 高階陣列方法 ### `map(callbackFn[, thisArg])` 概述:將陣列元素傳入`callback`函式,回傳的值將儲存於**新陣列** ```javascript let array = [1, 3, 5]; let newArray = array.map (function (num){ return num *= num }) console.log (newArray); // [1, 9, 25] ``` ### `filter(callbackFn[, thisArg])` 概述:將陣列元素傳入`callback`函式,符合判斷條件的值會回傳並儲存於**新陣列** ```javascript let array = [13, 46, 72, 94, 30, 45]; let pickEven = array.filter((num) => num %2 != 0); console.log (pickEven); // [13, 45] ``` ### `find(callbackFn[, thisArg])` 概述:將陣列元素傳入`callback`函式,回傳**第一個**符合判斷條件的值,沒有任何元素滿足條件時回傳`undefined` ```javascript let array = [34, 6, 455, 93, 199, 81]; let found = array.find((num) => num > 100); console.log (found); // 455 ``` ### `every(callbackFn[, thisArg])` 概述:將陣列元素傳入`callback`函式,檢查**每一個元素**是否符合判斷條件,回傳`boolean` ```javascript let array = [1, 2, 3, 4, 5]; let checkEven = array.every((num) => num %2 != 0); console.log (checkEven); // false let lessThanTen = array.every((num) => num < 10); console.log (lessThanTen); // true ``` ### `some(callbackFn[, thisArg])` 概述:將陣列元素傳入`callback`函式,逐一檢查元素是否符合判斷條件,**至少一個元素**符合判斷條件時回傳`true`,皆不符合時回傳`false` ```javascript let array = [1, 2, 3, 4, 5]; let checkEven = array.some((num) => num %2 != 0); console.log (checkEven); // true let moreThanTen = array.some((num) => num > 10); console.log (moreThanTen); // false ``` ### `reduce(callbackFn[, initialValue])` 概述:將陣列元素傳入`callback`函式取得回傳值,此回傳值在下一個元素進行新一輪迭代時可繼續調用,最終將陣列處理成**單一值** ```javascript let array = [1, 2, 3, 4, 5]; let total = array.reduce((accumulator, currentValue) => { return accumulator + currentValue; }, 0); // 設定初始值 console.log (total); // 15 ``` * syntax * `callback`函式中有以下四個參數: * `accumulator`:累加器,為上一次呼叫函式的回傳值 * `currentValue`:目前進行迭代的元素 * `currentIndex`(optional):目前進行迭代的元素的索引值 * `array`(optional):呼叫`reduce()`的陣列 * `initialValue`(optional):初次執行`callback`函式時傳入的累加器**初始值**。若未提供此初始值,將以**陣列的第一個元素**作為累加器初始值 ### `sort([compareFunction])` 概述:對陣列中的所有元素原地(in place)進行排序,再回傳排序後的陣列 ```javascript let weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri']; weekdays.sort(); console.log (weekdays); // ["Fri", "Mon", "Thu", "Tue", "Wed"] let numbers = [9, 33, 179, 2556, 11]; numbers.sort(); console.log (numbers); // [11, 179, 2556, 33, 9] ``` 其中`compareFunction`為選擇性,可自行定義排序方法。若省略此參數,則根據各元素轉為字串後的**Unicode編碼**進行排序 ### 參考文章 * [Array.prototype.map() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) * [Array.prototype.filter() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) * [Array.prototype.find() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) * [Array.prototype.every() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) * [Array.prototype.some() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) * [Array.prototype.reduce() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) * [Array.prototype.reduce() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) * [Array.prototype.sort() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) ## `Object.keys()`、`Object.value()`物件迴圈用法 ### `Object.keys()` 概述:將回傳的物件的key值組合成一個陣列 ```javascript const person = { name: 'Jon', age: 23, sex: 'male', pets: ['cats', 'dogs'] } Object.keys(person); // ["name", "age", "sex", "pets"] ``` ### `Object.value()` 概述:將回傳的物件的value值組合成一個陣列 ```javascript const person = { name: 'Jon', age: 23, sex: 'male', pets: ['cats', 'dogs'] } Object.values(person); // ["Jon", 23, "male", ["cats", "dogs"]] ``` ### `Object.entries()` 概述:將回傳的物件的key值及value值,以`[key, value]`的形式組合成一個陣列 ```javascript const person = { name: 'Jon', age: 23, sex: 'male', pets: ['cats', 'dogs'] } Object.entries(person); // [["name", "Jon"], ["age", 23], ["sex", "male"], ["pets", ["cats", "dogs"]]] ``` ### 參考文章 * [Object.keys() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) * [Object.values() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values) * [Object.entries() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries)