### 擴展運算符
擴展運算符(spread) 是三個點(...),它如同 `rest` 參數的逆運算,將一個數組轉為用逗號分隔的參數序列
```js
console.log(...[1, 2, 3])
// 1 2 3
```
由于擴展運算符可以展開數組,所以不再需要使用 `apply` 方法將數組轉為函數的參數
```js
function f (x, y, z) {}
let args = [1, 2, 3]
f(...args)
```
使用數組的擴展運算符簡化求出一個數組中的最大值
```js
Math.max(...[14, 3, 77])
// 等同于
Math.max(14, 3, 77)
```
另外一個例子是通過 `push` 方法將一個數組添加到另一個數組的后面
```js
let arr1 = [1, 2 , 3]
let arr2 = [4, 5, 6]
arr1.push(...arr2)
```
下面來看下擴展運算符的一些應用
#### 合并數組
```js
let more = [3, 4, 5]
[1, 2, ...more]
let arr1 = ['a', 'b']
let arr2 = ['c']
let arr3 = ['d', 'e']
[...arr1, ...arr2, ...arr3]
// ['a', 'b', 'c', 'd', 'e']
```
#### 與解構賦值結合,用于生成數組
#### 函數可以返回多個值
#### 字符串
擴展運算符可以將字符串轉為真正的數組
```js
[...'hello']
// ['h', 'e', 'l', 'l', 'o']
```
### Array.from()
`Array.from()`方法將兩類對象轉為真正的數組,類似數組的對象和可遍歷的對象,包括ES6新增的 `Set` 和 `Map`
```js
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
}
let arr = Array.from(arrayLike) // ['a', 'b', 'c']
```
實際應用中,常見的類似數組的對象時DOM操作返回的NodeList集合,以及函數內部的 `arguments` 對象。
```js
// NodeList對象
let ps = document.querySelectorAll('p')
Array.from(ps).forEach(p => {
console.log(p)
})
// arguments對象
function foo () {
let args = Array.from(arguments)
}
```
只要是部署了 `Interator` 接口的數據結構,`Array.from` 都可以將其轉換為數組
```js
Array.from('hello')
// ['h', 'e', 'l', 'l', 'o']
```
`Array.from` 還可以接受第二個參數,作用類似于數組的 `map` 方法,用來對每個元素進行操作,將處理后的值放入返回的數組。
```js
Array.from([1, 2, 3], (x) => x * x)
// [1, 4, 9]
```
### Array.of()
`Array.of()` 方法用于將一組值轉為數組
```js
Array.of(3, 11, 8) // [3, 11, 8]
Array.of(3) // [3]
Array.of(3).length // 1
```
`Array.of()` 基本上可以用來替代 `Array()` 或 `new Array()` ,并且不存在由于參數不同而導致的重載。
`Array.of()` 總是返回參數值組成的數組,如果沒有參數,就返回一個空數組。
### 數組實例的 copyWithin()
數組實例的 `copyWithin()` 方法會在當前數組內部將指定位置的成員復制到其他位置(會覆蓋原有成員),然后返回當前數組,也就是說,這個方法會修改當前數組。
```js
Array.prototype.copyWithin(target, start = 0, end = this.length)
```
它接受3個參數:
- `target`:必選,從該位置開始替換數據
- `start`:可選,從該位置開始讀取數據,默認0
- `end`:可選,到該位置停止讀取數據,默認為數組長度
```js
[1, 2, 3, 4, 5].copyWithin(0, 3)
// [4, 5, 3, 4, 5]
```
### 數組實例的 find() 和 findIndex()
數組實例的 `find()` 方法用于找出第一個符合條件的數組成員。它的參數是一個回調函數,所有數組成員依次執行該回調函數,直到找出第一個返回值為 `true` 的成員,然后返回該成員,如果沒有符合條件的成員,則返回 `undefined`
```js
[1, 4, -5, 10].find((n) => n < 0)
// -5
```
數組實例的 `findIndex()` 方法與 `find` 非常類似,返回第一個符合條件的數組成員的位置,如果沒找到,則返回 -1
```js
[1, 5, 10, 15].findIndex((value, index, arr) => {
return value > 9
})
// 2
```
### 數組實例的 fill()
`fill()` 方法用給定值填充一個數組
```js
['a', 'b', 'c'].fill(7)
// [7, 7, 7]
```
`fill()` 方法用于空數組的初始化非常方便,數組中已有的元素會被全部抹去。它還可以接受第二個和第三個參數,用于指定填充的起始位置和結束位置
```js
['a', 'b', 'c'].fill(7, 1, 2)
// ['a', 7, 'c']
```
### 數組實例的 entries()、keys() 和 values()
ES6提供了3個新的數組實例遍歷方法: `entries()`、`keys()` 和 `values()`,它們都可以用于遍歷數組,并返回一個遍歷器對象,可以用 `for...of` 循環遍歷。`keys()` 對鍵名進行遍歷,`values()` 對鍵值進行遍歷,`entries()` 對鍵值對進行遍歷。
```js
for (let index of ['a', 'b'].keys()) {
console.log(index)
}
// 0
// 1
```
```js
for (let elem of ['a', 'b'].values()) {
console.log(elem)
}
// 'a'
// 'b'
```
```js
for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem)
}
// 0 'a'
// 1 'b'
```
如果不使用 `for...of` 循環,也可以手動調用遍歷器對象的 `next()` 方法進行遍歷
### 數組實例的 includes()
`Array.prototpye.includes` 方法返回一個布爾值,表示某個數組是否包含給定的值,與字符串的 `includes()` 方法類似。
```js
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
[1, 2, NaN].includes(NaN) // true
```
該方法的第二個參數表示搜索的起始位置,默認為0,也可以為負數。
該方法與ES5中的 `indexOf` 很相似,但 `indexOf` 有兩個缺點,一是不夠語義化,二是它不能正確判斷 `NaN`