天天看點

ES6學習之 - rest參數和擴充運算符...

rest參數 ...

ES6 引入 rest 參數(形式為

...變量名

),用于擷取函數的多餘參數,這樣就不需要使用

arguments

對象了。rest 參數搭配的變量是一個數組,該變量将多餘的參數放入數組中。

function add(...values) {
  let sum = 0;

  for (var val of values) {
    sum += val;
  }

  return sum;
}

add(2, 5, 3) // 10
           

上面代碼的

add

函數是一個求和函數,利用 rest 參數,可以向該函數傳入任意數目的參數。

下面是一個 rest 參數代替

arguments

變量的例子。

// arguments變量的寫法
function sortNumbers() {
  return Array.prototype.slice.call(arguments).sort();
}

// rest參數的寫法
const sortNumbers = (...numbers) => numbers.sort();
           

上面代碼的兩種寫法,比較後可以發現,rest 參數的寫法更自然也更簡潔。

rest參數注意點:

rest 參數之後不能再有其他參數(即隻能是最後一個參數),否則會報錯。

// 報錯
function f(a, ...b, c) {
  // ...
}
           

擴充運算符 ...

擴充運算符(spread)是三個點(

...

)。它好比 rest 參數的逆運算,将一個數組轉為用逗号分隔的參數序列。

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>]

Math.max(...[14, 3, 77])
// 找到數組中最大值
           

該運算符主要用于函數調用。

function push(array, ...items) {
  array.push(...items);
}

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

const numbers = [4, 38];
add(...numbers) // 42
           

上面代碼中,

array.push(...items)

add(...numbers)

這兩行,都是函數的調用,它們都使用了擴充運算符。該運算符将一個數組,變為參數序列。

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

function f(v, w, x, y, z) { }
const args = [0, 1];
f(-1, ...args, 2, ...[3]);
           

擴充運算符後面還可以放置表達式。

const arr = [
  ...(x > 0 ? ['a'] : []),
  'b',
];
           

擴充運算符的應用

(1)複制數組

擴充運算符提供了複制數組的簡便寫法。

const a1 = [1, 2];
// 寫法一
const a2 = [...a1];
// 寫法二
const [...a2] = a1;
           

上面的兩種寫法,

a2

都是

a1

的克隆。

(2)合并數組

擴充運算符提供了數組合并的新寫法。

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

// ES5 的合并數組
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]

// ES6 的合并數組
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]
           

不過,這兩種方法都是淺拷貝,使用的時候需要注意。

const a1 = [{ foo: 1 }];
const a2 = [{ bar: 2 }];

const a3 = a1.concat(a2);
const a4 = [...a1, ...a2];

a3[0] === a1[0] // true
a4[0] === a1[0] // true
           

上面代碼中,

a3

a4

是用兩種不同方法合并而成的新數組,但是它們的成員都是對原數組成員的引用,這就是淺拷貝。如果修改了原數組的成員,會同步反映到新數組。

(3)與解構指派結合

擴充運算符可以與解構指派結合起來,用于生成數組。

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

下面是另外一些例子。

const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest  // [2, 3, 4, 5]

const [first, ...rest] = [];
first // undefined
rest  // []

const [first, ...rest] = ["foo"];
first  // "foo"
rest   // []
           

如果将擴充運算符用于數組指派,隻能放在參數的最後一位,否則會報錯。

const [...butLast, last] = [1, 2, 3, 4, 5];
// 報錯

const [first, ...middle, last] = [1, 2, 3, 4, 5];
// 報錯
           

(4)字元串

擴充運算符還可以将字元串轉為真正的數組。

[...'hello']
// [ "h", "e", "l", "l", "o" ]