ES6入門之數組的擴展

1. 擴展運算符

...表示,將一個數組轉爲用逗號分隔的參數序列,以下:前端

console.log(...[1,2,3]) // 1 2 3

console.log(1, ...[2,3,4], 5) // 1 2 3 4 5

[...document.querySelectorAll('div')] // [<div>, <div>, <div>]


function add(x, y){
    return x + y
}
const n = [3, 5]
add(...n) // 8
複製代碼
擴展運算符能夠和正常函數結合使用,以下:
function f(a,b,c,d,e){
    console.log(a,b,c,d,e)
}
const age = [0,1]

f(-1,...age,2,...[3]) // -1 0 1 2 3
複製代碼
擴展運算符後面也能夠是表達式,以下:
const x = 10
const arr = [
    ...(x > 0 ? ['a'] : []), 'b',
]

arr // ['a', 'b']
複製代碼
重要:若是擴展運算符後面是一個空數組,將不會有任何效果。另外只有在函數調用的時候擴展函數在放在圓括號以內,其餘的則會報錯。
替代函數的apply方法

擴展函數能夠展開數組,因此將不須要apply方法來將數組轉換爲函數的參數。node

function f(x, y, z){
    console.log(x, y, z)
}

var a = [1,2,4]

// ES5 
f.apply(null, args)

// ES6
f(...a)


// Math.max方法

//ES5
Math.max.apply(null, [14, 3, 99])

//ES6
Math.max(...[12, 4, 55])

//等同於
Math.max(12, 4, 55)

// push方法的應用

var a = [0,1,2]
var b = [3,4,5]

//ES5
Array.prototype.push.apply(a,b) // 0,1,2,3,4,5

//ES6
a.push(...b)
複製代碼
擴展運算符的應用
  1. 複製數組算法

    由於數組是複合的數據類型,直接的複製只是複製數組在堆內存中的指針地址
     
     const a1 = [1,2]
     const a2 = a1
     
     a2[0] = 3
     a1 // [3,2]
    
     // ES5 經過變通方法來複制
     const a1 = [1,2]
     const a2 = a1.concat()
    
     a2[0] = 23
     a1 // [1,2]
     
     // ES6寫法
     const b1 = [1,3]
     const b2 = [...b1] or [...b2] = b1
    複製代碼
  2. 合併數組segmentfault

    const a1 = ['b', 'c']
     const a2 = ['d']
     const a3 = ['x', 'y']
     
     // ES5中合併數組
     a1.concat(a2, a3)
     
     // ES6中合併數組
     [...a1, ...a2, ...a3]
    
     //以上兩種都是淺拷貝,修改原數組和同步新數組
    複製代碼
  3. 與解構賦值一塊兒使用,擴展只能放在最後一位,否則會報錯數組

    // ES5
     a = list[0], rest = list.slice(1)
    
     // ES6
     [a,...rest] = list
    
     // 其餘
     const [a,...c] = [1,2,4,5,4,6] // a 1   c 2,4,5,4,6
     const [a,...c] = [] // a undefined   c []
     const [a,...c] = ['a'] // a 'a'   c []  
    複製代碼
  4. 字符串,將字符串轉換爲數組瀏覽器

    [...'hello'] // [h,e,l,l,0]
    複製代碼
  5. 實現了Iterator接口的對象數據結構

    任何定義了遍歷器接口對象,均可以用擴展運算符轉爲真正的數組
    
     let nodelist = document.querySelectorAll('div')
     let array = [...nodelist]
     // querySelectorAll 返回的是一個類數組,經過擴展運算符
     將其轉換爲一個真正的數組
    複製代碼
  6. Map 和 Set 解構,Generator函數app

    擴展運算符調用的是數據解構的Iterator接口,只要有Iterator接口的
     對象,均可以使用擴展運算符
    
     // Map
     let map = new Map([
         [1, 'a'],
         [2, 'b'],
         [3, 'c'],
     ])
     let arr = [...map.keys()] // 1, 2, 3
     let arr = [...map.values()] // 'a', 'b', 'c'
     
     //Generator函數
     const go = function*(){
         yield 1;
         yield 2;
         yield 3;
     }
     [...go()] // [1, 2, 3]
    複製代碼

2. Array.from()

Array.from 方法用於將兩類對象轉爲真正的數組。一、相似數組對象 和 可遍歷的對象(包裹Set和Map),以下:dom

let arrLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
}

// ES5 
var a1 = [].slice.call(arrLike)

// ES6
var a2 = Array.from(arrLike)
複製代碼

在實際中,像獲取dom後返回的Nodelist集合,以及函數內部的arguments對象就是類數組,經過 Array.from將它們轉換爲真正的數組。函數

// NodeList 對象
let ps = document.querySelectorAll('p')
Array.from(ps).filter(p => {
    return p.textContent.length > 100
})

// arguments 對象
function foo(){
    var arg = Array.from(arguments)
}

// 只要部署了Iterator接口的數據解構,Array.from都能將其轉成數組
Array.from('hello') // ['h', 'e', 'l', 'l', 'o']

let nl = new Set([1, 2])
Array.from(nl) // [1, 2]

// 若是是真數組則返回同樣的
Array.from([1, 2, 3]) // [1, 2, 3]
複製代碼

... 擴展運算符也能夠將某些類數組轉換爲數組,如arguments和NodeList集合

擁有lenght屬性的對象均可以經過Array.from轉換爲數組,而擴展運算符則不行。

Array.from({lenght:3}) // [undefined, undefined, undefined]
複製代碼

對於低版本的瀏覽器,能夠經過 Array.prototype.slice 方法替代

Array.from 還能夠接受第二個參數如同map同樣,用來對每一個元素進行操做,並將處理後的值放入返回的數組中。

const arrlike = new Set([1,2,3])
Array.from(arrlike, x => x * x)   // =
Array.from(arrlike).map(x => x * x)   // [1, 4, 9]

//注意: 若是map中用到了this,能夠傳入Array.from
的第三個參數,用來綁定this
複製代碼

Array.from 能夠將各類值轉換爲真正的數組,而且還提供map相關功能,這樣表明若是有個原始數據結構,能夠先將他轉換爲數組,而後使用數組相關的方法。

3. Array.of()

用於將一組值,轉換爲數組。主要用來彌補Array函數由於參數個數不一樣而致使的差別

Array.of(3,11,6) // [3, 11, 6]
Array.of(3) // [3]
Array.of(4).length // 1
複製代碼

4. 數組的實例 copyWithin()

將當前數組中指定位置的元素複製到另一個位置,而且會覆蓋那個位置的原有元素,會修改當前數組

// 有三個參數
1. target(必須):從該位置開始替換數據,若是是負值,則倒數
2. start(可選):從該位置讀取數據,默認0,負值同上
3. end(可選):到這個位置中止讀取數據,默認等於數組長度,負值同上

    
let p = [1,2,3,4,5,6,7]
p.copyWithin(0,5,7)
[6, 7, 3, 4, 5, 6, 7]
複製代碼

5. 數組實例的 find() 和 findIndex()

find 用來找出數組中符合條件的成員,它的參數是一個回調函數,找到一個返回值爲true的返回,若是沒有則返回undefined

let s = [1,2,3,4,5,6]

s.find(x => x > 4)
// 5

find 方法的回調函數有三個參數
    
    value // 當前值
    index // 當前的位置
    arr // 原數組
複製代碼

findIndex 同find方法相似,只不過都不符合返回的是 -1,並且符合是返回符合條件值的位置而不是值。

let s = [1,2,3,4,5,6]

s.find(x => x > 4)
// 4
複製代碼

find 和 findIndex 均可以接受第二個參數

function o(p){
    return p > this.age
}

const u = {name: 'cx', age: 11}
const y = [8,11,22,2,4]

y.find(o, u) // 22  返回的值
y.findIndex(o, u) // 2  返回值的位置
複製代碼

6. 數組實例的 fill()

經過給定值,填充一個數組

let sz = [1,2,3,4,5,6]

sz.fill(1) // [1,1,1,1,1,1]

sz.fill(1,0,3) 
// 接受三個參數,第一個爲填充值,第二個爲起始位置,第三個爲截至位置

sz.fill(1,3)
// 若是省略最後一個參數,則默認從起始位置到數組默認長度結束
複製代碼

7. 數組實例的 entries(), keys(), values()

三種方法主要用於遍歷數組,能夠用 for...of...進行遍歷,keys()對應鍵名,values對應鍵值,entries()對鍵值對的遍歷

let bo = ['a', 'c']

for(let r of bo.keys()){
	console.log(r) // 0 1
}
// 0 1

for(let n of bo.values()){
	console.log(n) 
}
// a c

for(let s of bo.entries()){
	console.log(s)
}
// [0, "a"]
// [1, "c"]
複製代碼

8. 數組實例的 includes()

用來表示某個數組是否包含給定的值,返回一個布爾值

let i = ['a',1,2,3]

i.includes()  // false
i.includes(1) // true
i.includes(10) // false
複製代碼

indexOf 和includes 的區別

indexOf // 不夠語義化,它的做用是找到參數出現的第一個位置,
因此要比較是否爲 -1,另外因爲 內部使用的是 ===  則致使NaN
的誤判。

// [NaN].indexOf(NaN) // -1

includes // 使用的是不同的算法,則不會有這個問題

// [NaN].includes(NaN) // true
複製代碼

Map 和 Set 的has 方法和includes的區別

Map 的has 方法是用來查找鍵名的
Set 的has 方法是用來查找值的
複製代碼

9. 數組的實例 flat(), flatMap()

flat() 將嵌套的二維數組變成一維數組,若是須要拉平多維數組,則flat(多維數量) 或者使用 Infinity 直接轉爲一維數組

let rw = [1,2,3,[4,5,6],7]
rw.flat()  // [1, 2, 3, 4, 5, 6, 7]

let dw =  [1,2,3,[4,5,6,[7,8],[2,['a','b'],4,5]],[5,6,]]
dw.flat(3) // [1, 2, 3, 4, 5, 6, 7, 8, 2, "a", "b", 4, 5, 5, 6]

// 若是你不知道是多少層嵌套而都想轉成一維,能夠使用 Infinity
dw.flat(Infinity) 
// [1, 2, 3, 4, 5, 6, 7, 8, 2, "a", "b", 4, 5, 5, 6]
複製代碼

flatMap() 對數組執行map,而後對返回值組成的數組 執行flat,不會改變原數組。flatMap只能展開一層數組。

let mp = [2,3,4,5]

mp.flatMap((item) => [item, item* 2])
// [2, 4, 3, 6, 4, 8, 5, 10]
====
mp.map((item) => [item, item*2])
// [[2,4],[3,6],[4,8],[5,10]]
mp.flat()
// [2, 4, 3, 6, 4, 8, 5, 10]    
複製代碼

10. 數組的空位(避免出現空位)

數組的空位指的是該數組中某一個位置沒有任何值。另外空位不是undefined,若是一個位置的值是undefined,那麼這個位置仍是有值的。

Array(3) // [, , ,]
複製代碼

ES5中大多數狀況中對待空位都是會忽略

- forEach(), filter(), reduce(), every() 和 some() 都會跳過空位
- map() 跳過但保留這個值
- join() 和 toString() 中 空位 === undefined,而 undefined和null會被處理成空字符串
複製代碼

ES6 中 空位則轉換爲undefined

- Array.from([1,,2]) // [1, undefined, 2]
- [...['a',,'b']]    // [ "a", undefined, "b" ]

entries()
keys()
values()
find()
findIndex()  // 都會將空位處理成undefined。
複製代碼

歡迎關注 公衆號【小夭同窗】

歡迎關注 公衆號【小夭同窗】

ES6入門系列

ES6入門之let、cont

ES6入門之變量的解構賦值

ES6入門之字符串的擴展

ES6入門之正則的擴展

ES6入門之數值的擴展

ES6入門之函數的擴展

Git教程

前端Git基礎教程

相關文章
相關標籤/搜索