Jun

只要我的心還會跳,腿還能動

我就沒有理由停下前進的步伐

ES6 展開運算符與其餘運算符


展開運算符

用於將一個陣列展開成個別的值,像這樣

const arr = ['A', 'B', 'C'];

console.log(...arr); // A B C

❗️ 該運算符後面必定接著一個陣列

傳統的合併陣列作法

let arr1 = ['A', 'B', 'C'];
let arr2 = ['D', 'E'];
let arr3 = arr1.concat(arr2);

console.log(arr3); // ["A", "B", "C", "D", "E"]

使用展開運算符

let arr1 = ['A', 'B', 'C'];
let arr2 = ['D', 'E'];
let arr3 = [...arr1, ...arr2];

console.log(arr3); // ["A", "B", "C", "D", "E"]

基於陣列是傳址的關係,所以如果這麼做

const arr1 = ['A', 'B', 'C'];
const arr2 = arr1;
arr2.push('D');

console.log(arr1); // ["A", "B", "C", "D"]

即便是 arr2push 的動作,arr1 仍然會受到影響,但如果我們希望避免這樣的情況發生,就可以使用展開運算符,像這樣

const arr1 = ['A', 'B', 'C'];
const arr2 = [...arr1];
arr2.push('D');

console.log(arr1); // ["A", "B", "C"]

常見的情況是我們在取得多個 DOM 元素時,拿到的陣列是類陣列(Array-like),它不是真的陣列,從它原型上的方法就可以看得出來比起真正的陣列少上許多,如果我們要把它轉為真正的陣列,也可以使用展開運算符,相當方便,像這樣

<body>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>

  <script>
    const boxs = document.querySelectorAll('.box');
    console.log(boxs); // NodeList [div.box, div.box, div.box]

    const realArray = [...boxs];
    console.log(realArray); // [div.box, div.box, div.box]
  </script>
</body>

相同的概念,我們一樣可以使用展開運算符將函數中的偽物件(arguments)轉為真正的陣列物件,像這樣

function func() {
  console.log(arguments); // Arguments ["A", "B", "C", "D", "E"]

  const realArray = [...arguments];
  console.log(realArray); // ["A", "B", "C", "D", "E"]
}

func('A', 'B', 'C', 'D', 'E');

將可迭代物件或類陣列物件轉為真正的陣列,JavaScript 裡內建的可迭代物件有 String、Array、TypedArray、Map、Set 物件,以字串為例

const str = 'Hello';
const arr = [...str];

console.log(arr); // ["H", "e", "l", "l", "o"]
function func(x, y, z) {
  console.log(x); // 5
  console.log(y); // 10
  console.log(z); // 15

  return x + y + z;
}

const arr = [5, 10, 15];

console.log(func(...arr)); // 30

其餘運算符

用於收集剩餘的值,將其轉為陣列。常用於定義函數時的參數識別名定義。

當傳給函數的參數數量不明確時,我們就可以使用其餘參數收集不定數量的參數並轉為陣列,像這樣

function func(...words) {
  console.log(words); // ["A", "B", "C"]
}

func('A', 'B', 'C');

❗️ 其餘參數在傳入時必定位於末置位且參數中只能存在一個其餘參數

❗️ 其餘參數若沒接收到值,那它會成為空陣列而非 undefined

function func(par, ...words) {
  console.log(par); // undefined
  console.log(words); // []
}

func();

當其餘參數前有其它參數時,如上所述,以收集剩餘參數的行為將其轉為陣列,以下

function func(par, ...words) {
  console.log(par); // A
  console.log(words); // ["B", "C"]
}

func('A', 'B', 'C');

其餘參數主要還是用於取代函數中的偽陣列物件(arguments),雖然它與其餘參數的表現形式差不多,但實質上卻沒有真的陣列該有的方法,使用起來相當不便且容易造成混淆。