## `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)