ES6指北【5】——展開語法(spread syntax)

咱們先來看一看MDN的官方定義javascript

展開語法(Spread syntax), 能夠在 函數調用/數組構造時, 將 數組表達式或者 string在語法層面展開;
還能夠在 構造字面量對象時, 將 對象表達式按key-value的方式展開。(譯者注: 字面量通常指 [1, 2, 3] 或者 {name: "mdn"} 這種簡潔的構造方式)

從定義咱們能夠了解到展開語法的使用場景以下java

  • 函數調用
  • 數組構造
  • 構造字面量對象(ES2018)

做用以下api

  • 展開數組
  • 展開字符串
  • 展開對象只能用於構造字面量對象

1. 在函數調用時使用

// 展開數組
console.log(...[1,2,3]) // 1 2 3

// 展開字符串
console.log(...'hello world') // h e l l o   w o r l d

// 展開對象【沒法使用,會報錯】
console.log(...{a:1}) // Uncaught TypeError

1.1 與rest參數對比

在函數調用時使用展開語法時,須要特別注意數組、字符串實際上是被展開成了參數序列
還記得rest參數將參數都都收集爲數組嗎?
展開語法正好是它的逆運算——將數組展開爲參數
還有注意的是rest參數在函數定義時使用【處理形參】,展開語法在函數調用時使用【處理實參】,可能有些拗口,下面看個例子你們就明白了數組

function test(x, y, ...params) {
  // 定義一個函數時,使用的是rest參數
  console.log(...params) // 調用一個函數時,使用的是rest參數
}

1.2 做爲apply的語法糖

let numArr = [1, 10, 2, 234]
Math.max.apply(null, numArr)
// 徹底等價於
Math.max(...numArr) // 將numArr展開爲參數序列

1.3 在new的時候使用

由於new的時候是沒法調用apply的,因此展開語法這個時候起到了很牛X的做用瀏覽器

function Person(name, age, weight) {
  this.name = name
  this.age = age
  this.weight = weight
}

let blues = new Person('blueswong', '16', '60')
// 徹底等價於
let blues = new Person(...['blueswong', '16', '60'])

這在須要生產不少個實例時,很是有用app

function Person(name, age, weight) {
  this.name = name
  this.age = age
  this.weight = weight
}

let persons = [['blues1', '16', '60'], ['blues2', '16', '60'], ['blues3', '16', '60']]
let createdPersons = {}
persons.forEach(e => {
  console.log(e[0])
  createdPersons[e[0]] = new Person(...e)
})

2. 在數組構造時使用

// 展開數組
let arr1 = [1, 2, 3]
let arr2 = [0, ...arr1, 4] // [0, 1, 2, 3, 4]

// 展開字符串
let arr1 = [1, 2, 3, ...'456'] // [1, 2, 3, "4", "5", "6"]

2.1 代替將已有數組元素插入到新數組重的全部API

以往咱們將已有數組的 元素插入到新數組的中,須要借用一些API例如 push/unshift/splice/concat,如今咱們使用展開語法能夠對上述api進行替換。

須要特別強調的是,這在建立新數組的時候才比較方便函數

let arr = [4, 5]
let arr2 = [6, 7, 8]
// 在數組任意位置增長元素
let newArr1 = [1, 2, 3, ...arr] // [1, 2, 3, 4, 5]
let newArr2 = [...arr, 1, 2, 3] // [4, 5, 1, 2, 3]
let newArr3 = [1, ...arr, 2, 3] // [1, 4, 5, 2, 3]
let newArr4 = [1, 2, ...arr, 3] // [1, 2, 4, 5, 3]
// 鏈接兩個數組
let newArr5 = [...arr, ...arr2] // [4, 5, 6, 7, 8]

若是是對原有的數組進行操做原有API+在函數調用中使用展開語法比較方便this

2.2 實現對數組的淺拷貝

let obj = {a: 1}
let arr = [2, 1, '的', obj]
// 在數組任意位置增長元素
let newarr = [...arr] // [2, 1, '的', {a: 1}]

// 但僅僅是淺拷貝,新數組中的{a:1}與obj仍是指向了相同的內存
newarr[3].a = 2
console.log(obj) // {a: 2}

3. 在構造字面量對象時使用

3.1 實現對象的淺拷貝

常見的實現對象淺拷貝的方法
let obj = {a: '10', b: {c: 10}, d: [1, 2, 3]}

// 1. 遍歷
let newObj = {}
for (let key in obj) {
  newObj[key] = obj[key]
}
console.log(newObj)

// 2.使用assign
let newObj1 = Object.assign({}, obj)
console.log(newObj1)
使用展開語法實現
let newObj2 = {...obj}
因爲這是ES2018的語法,如今瀏覽器支持的並不到位,所以筆者就不作過多介紹了。你們能夠 去mdn上查看
相關文章
相關標籤/搜索