[ES6 展開運算子(Spread Operator)、其餘參數(Rest Operator)]

一、展開運算子(Spread Operator)

1. 功能

  • 展開: 展開運算子可以將陣列展開成個別數值

  • 合併: 使用兩個以上的展開運算子合併陣列

  • 轉換: 展開運算子可以將類陣列(array-like)和可迭代(iterable)變成陣列(array)

  • 淺層拷貝: 複製一個陣列,並且這個陣列與原本的陣列沒有傳參考的特性

    a. 展開

  • 展開運算子可以將陣列展開成個別數值

    1
    2
    3
    const array = ['可', '黏', '阿']

    console.log(...array) // 可 黏 阿
  • 也可以將字串展開

    1
    2
    3
    const str = 'FaDaChia';

    console.log(...str); // F a D a C h i a
  • 將陣列展開,帶入函式

    1
    2
    3
    4
    5
    function add(a, b, c) {
    return a + b + c
    }
    const args = [1, 2, 3]
    add(...args) // 6

    b. 合併

    將陣列展開成數值後,再用陣列[]合併成陣列

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    const array1 = ['你', '有', '點' ,',']
    const array2 = ['可', '黏', '阿']

    console.log([...array1, ...array2])
    //['你', '有', '點', ',', '可', '黏', '阿']

    //========對照過去 ES5 方法==============
    //使用 concat 合併陣列
    const array1 = ['祝', '大','家' ,',']
    const array2 = ['發', '大','財']

    const ARR = array1.concat(array2);
    console.log(ARR); // ["祝", "大", "家", ",", "發", "大", "財"]

c. 轉換

  • 可迭代 (iterable) 轉換成陣列 (array),可迭代物件包括 String、Array、TypedArray、Map 與 Set 物件
1
2
3
// 將字串轉換成陣列
const str = 'ptt'
const strTran = [...str]; // ["p", "t", "t"]
  • 類陣列轉換成陣列
1
2
3
4
5
6
7
8
9
10
11
function func(x){
console.log(arguments) // Arguments(4)[1, 2, 3, 4, callee: ƒ, Symbol(Symbol.iterator): ƒ]
console.log(Array.isArray(arguments)) // false

//轉為陣列
const arr = [...arguments]
console.log(arr) // [1, 2, 3, 4]
console.log(Array.isArray(arr)) // true
}

func(1, 2, 3, 4)

d. 淺層拷貝

陣列及物件都有傳參考的特性,當把他們賦予一個新的變數時,修改新的變數的值時,原陣列或物件也會被修改到

1
2
3
4
5
6
const name = ['Vicky', 'Eric', 'Pai']
const nameNew = name;
nameNew.push('小黑');

console.log(name); //["Vicky", "Eric", "Pai", "小黑"]
console.log(nameNew); //["Vicky", "Eric", "Pai", "小黑"]

展開運算子有淺層拷貝的特性,因此使用展開後,原陣列就不會被修改到了

1
2
3
4
5
6
const name = ['Vicky', 'Eric', 'Pai']
const nameNew = [...name];
nameNew.push('小黑');

console.log(name); //["Vicky", "Eric", "Pai"]
console.log(nameNew); //["Vicky", "Eric", "Pai", "小黑"]

But,因為是淺拷貝,所以當陣列裡面的值擺放的是物件的話,使用展開運算子後依然會被修改到

1
2
3
4
5
6
const name = [{Vicky: 20}, {Eric: 25}, {Pai: 29}]
const nameNew = [...name];
nameNew[0].Vicky = 30;

console.log(name); //[{Vicky: 30}, {Eric: 25}, {Pai: 29}]
console.log(nameNew); //[{Vicky: 30}, {Eric: 25}, {Pai: 29}]

如果不想被修改到得使用深拷貝,

1
2
3
4
5
6
const name = [{Vicky: 20}, {Eric: 25}, {Pai: 29}]
const nameNew =JSON.parse(JSON.stringify(name))
nameNew[0].Vicky = 30;

console.log(name); //[{Vicky: 30}, {Eric: 25}, {Pai: 29}]
console.log(nameNew); //[{Vicky: 20}, {Eric: 25}, {Pai: 29}]

二、其餘參數(Rest Operator)

有時傳進來的的參數不確定有多少,這時就可以使用其餘參數把不確定的參數變成陣列傳到函式

  • 單傳一個其餘參數

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function sum(...numbers) {
    let result = 0;
    numbers.forEach(function (number) {
    result += number;
    });
    return result;
    }

    console.log(sum(1)); // 1
    console.log(sum(1, 2, 3, 4, 5)); // 15
  • 其餘參數合併其他參數傳入
    如果 function 的參數裡面有先定義好的參數,會照順序把數值放到參數裡面,其他的才放到其餘參數裡面

    1
    2
    3
    4
    5
    6
    7
    function restArray(x, y, ...others) {
    console.log("x",x); // x: 1
    console.log("y",y); // y: 2
    console.log("others",others); // others: [3, 4, 5]
    }

    restArray(1, 2, 3, 4, 5);

三、資料來源

四、關鍵字

可迭代、深拷貝

0%