ES6 - 擴展運算符


ES6 擴展運算符

含義

概念

擴展運算符(spread)是三個點(...). 它好比rest參數的逆運算, 將一個數組轉為用逗號分隔的參數序列

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

/* ---------------- */
let arr = [...document.querySelectorAll('li')]
console.log(arr) //[li.spc, li.spc.sss, li, li, li.spc, li.spc, li]

主要用於函數的調用

// 在這個方法中, 因為我們的item參數本身就是一個數組, 所以, 傳入一個數組的話,會再套一層
// 放的是使用 `...`解開便是了
// 真正的使用, 應該是push(arr, 1, 2)
function push(array, ...item) {
  array.push(...item)
}
let arr = ['a', 'b', 'c']
const items = [1, 2, 3]
push(arr, items)
console.log(arr) // [ 'a', 'b', 'c', [ 1, 2, 3 ] ]


function add(x, y) {
  return x + y
}

const numbers = [1, 2]
let res = add(...numbers)
console.log(res) // 3

擴展運算符與正常的函數參數可以結合使用, 非常靈活

function f(v, w, x, y, z) {
  // 這里剛剛好, 所有的參數分開接收
  // -1, 0, 1, 2, 3
}
const args = [0, 1]
f(-1, ...args, 2, ...[3])

擴展運算符后面還可以放置表達式

const x = 1
const arr = [
  ...(x > 0 ? ['a'] : []),
  'b'
]
console.log(arr) //[ 'a', 'b' ]

如果擴展預算符后面是一個空數組, 則不會產生任何效果

const arr = [...[], 1]
console.log(arr) //[ 1 ]

代替數組的apply方法

不再需要applay將數組轉為函數的參數

// ES5 
function f(x, y, z) {
  // ...
  console.log(x)
}
var args = [0, 1, 2]
// 因為apply后面跟的是一個數組
f.apply(null, args)

// ES6
function f(x, y, z) {
  // ...
}
let args = [0, 1, 2]
f(...args)

簡化Math.max方法

// ES5
Math.max.apply(null, [14, 13, 55])

// ES6
Math.max(...[14, 13, 55])

// 等同於
Math.max(14, 13, 55)

push函數的直接使用

將一個數組添加到另一個數組的尾部

// ES5的寫法
var arr1 = [0, 1, 2]
var arr2 = [3, 4, 5]
Array.prototype.push.apply(arr1, arr2) // 因為push的參數不能是數組, 只能通過apply的方式, 來改變
console.log(arr1) // [ 0, 1, 2, 3, 4, 5 ]

// ES6的寫法
let arr1 = [0, 1, 2]
let arr2 = [3, 4, 5]
arr1.push(...arr2)
console.log(arr1) // [ 0, 1, 2, 3, 4, 5 ]

new Date()的時候直接使用

// 非常不理解這里的null, 是干嘛的
// 如果是apply的話, 第一個參數改變this, 已經改變成了Date, 第二個參數是一個數組, 里面是真正的參數, 我們真正參數的第一個就是年份啊.
var date = new (Date.bind.apply(Date, [null, 2015, 1, 1]))
console.log(date) // 2015-01-31T16:00:00.000Z

var date = new Date(...[2015, 1, 1])
console.log(date) // 2015-01-31T16:00:00.000Z

var date = new Date(2015, 1, 1)
console.log(date)//2015-01-31T16:00:00.000Z

擴展運算符的應用

復制數組

// 普通的復制只能是復制指針, 並不能真正的復制整個數組
const a1 = [1, 2]
const a2 = a1
a2[0] = 2
a1 // [ 2, 2 ]

// ES5: 通過變通方式來實現
const a1 = [1, 2]
const a2 = a1.concat()

// ES6: 更簡便的方式, 均可以克隆整個數組
const a1 = [1, 2]
const a2 = [...a1]
const [...a3] = a1

合並數組

// ES5
var arr = [1, 2].concat(more)
// ES6
var arr = [1, 2, ...more]

var arr1 = ['a', 'b']
var arr2 = ['c']
var arr3 = ['d', 'e']

// ES5
arr1.concat(arr2, arr3)
//ES6
var arr = [...arr1, ...arr2, ...arr3]

與解構賦值結合

// 生成數組
var list = ['a', 'b', 'c', 'd']

// ES5
a = list[0], rest = list.slice(1)

// ES6
const [a, ...rest] = list

console.log(a) // a
console.log(rest) // [ 'b', 'c', 'd' ]
const [first, ...rest] = [1, 2, 3, 4, 5]
console.log(first) // 1
console.log(rest) // [2, 3, 4, 5]

const [first, ...rest] = []
console.log(first) // undefined
console.log(rest) // []

const [first, ...rest] = ['foo']
console.log(first) // 'foo'
console.log(rest) // []
// 如果擴展運算符沒有把數組放到最后一位會報錯
const [...butLast, last] = [1, 2] // 報錯: Rest element must be last element
 
const [first, ...middle, last] = [1, 2, 3, 4, 5]; // 報錯: Rest element must be last element

Unicode編碼字符串求長

// 轉化字符串
console.log([...'hello']) //[ 'h', 'e', 'l', 'l', 'o' ]

// 可以識別編碼
console.log('x\uD83D\uDE80y') // x�y
console.log('x\uD83D\uDE80y'.length) // 4 // 會把四個字符的Unicode字符是被為兩個字符
console.log([...'x\uD83D\uDE80y']) // [ 'x', '�', 'y' ]
console.log([...'x\uD83D\uDE80y'].length ) // 3 // 擴展運算符可以正常返回字符串的長度

// 檢測帶有Unicode字符串的長度
function length(str) {
  return [...str].length
}

// 所有涉及到操作四個字節的Unicode字符的函數, 都有問題, 需要使用運算符改寫
let str = 'x\uD83D\uDE80y'
str.split('').reverse().join('')
const arr = [...str].reverse().join('')

實現Iterator接口的對象

// 任何Iterator接口對象, 都能通過擴展運算符變為真正的數組
let nodeList = document.querySelectorAll('li')
let array = [...nodeList]

// 沒有部署Iterator接口的類數組, 無法通過擴展運算符進行轉化
let arrayLike = {
  0: 'a',
  1: 'b',
  2: 'c',
  length: 3
}

// let arr1 = [...arrayLike] // 報錯: arrayLike[Symbol.iterator] is not a function


let arr2 = Array.from(arrayLike) // 報錯: arrayLike[Symbol.iterator] is not a function
console.log(arrayLike) // { '0': 'a', '1': 'b', '2': 'c', length: 3 }
console.log(arr2) // [ 'a', 'b', 'c' ]

Map 和 Set 結構, Generator函數

// Map結構
// 擴展運算符內部調用的是數據結構的Iterator接口
// Map具有Iterator接口, 可以使用擴展運算符
let map = new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three']
])

console.log(map) //Map { 1 => 'one', 2 => 'two', 3 => 'three' }
let arr1 = [...map.keys()]
console.log(arr1) //[ 1, 2, 3 ]
// Generator 函數運行后, 返回的遍歷器對象
const go = function*() {
  yield 1;
  yield 2;
  yield 3;
};
console.log(go) // [GeneratorFunction: go]
console.log(go()) // {}
// 返回遍歷器對象, 執行擴展運算符
let arr2 = [...go()]
console.log(arr2) // [ 1, 2, 3 ]

參考(都能說是抄襲了.. 捂臉..)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM