---
# System prepended metadata

title: JavaScript中的高階陣列方法

---

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