1. 程式人生 > >es6擴充套件運算子 三個點(...)

es6擴充套件運算子 三個點(...)

1  含義

擴充套件運算子( spread )是三個點(...)。它好比 rest 引數的逆運算,將一個數組轉為用逗號分隔的引數序列。

[javascript] view plain copy 在CODE上檢視程式碼片派生到我的程式碼片
  1. console.log(...[1, 2, 3])  
  2. // 1 2 3
  3. console.log(1, ...[2, 3, 4], 5)  
  4. // 1 2 3 4 5
  5. [...document.querySelectorAll('div')]  
  6. // [<div>, <div>, <div>]

該運算子主要用於函式呼叫。
[javascript] 
view plain
 copy 在CODE上檢視程式碼片派生到我的程式碼片
  1. function push(array, ...items) {  
  2. array.push(...items);  
  3. }  
  4. function add(x, y) {  
  5. return x + y;  
  6. }  
  7. var numbers = [4, 38];  
  8. add(...numbers) // 42
上面程式碼中,array.push(...items)和add(...numbers)這兩行,都是函式的呼叫,它們的都使用了擴充套件運算子。該運算子將一個數組,變為引數序列。

擴充套件運算子與正常的函式引數可以結合使用,非常靈活。

[javascript]
 view plain copy 在CODE上檢視程式碼片派生到我的程式碼片
  1. function f(v, w, x, y, z) { }  
  2. var args = [0, 1];  
  3. f(-1, ...args, 2, ...[3]);  
2  替代陣列的 apply 方法

由於擴充套件運算子可以展開陣列,所以不再需要apply方法,將陣列轉為函式的引數了。

[javascript] view plain copy 在CODE上檢視程式碼片派生到我的程式碼片
  1. // ES5 的寫法
  2. function f(x, y, z) {  
  3. // ...
  4. }  
  5. var args = [0, 1, 2];  
  6. f.apply(null, args);  
  7. // ES6 的寫法
  8. function f(x, y, z) {  
  9. // ...
  10. }  
  11. var args = [0, 1, 2];  
  12. f(...args);  

下面是擴充套件運算子取代apply方法的一個實際的例子,應用Math.max方法,簡化求出一個數組最大元素的寫法。 [javascript] view plain copy 在CODE上檢視程式碼片派生到我的程式碼片
  1. // ES5 的寫法
  2. Math.max.apply(null, [14, 3, 77])  
  3. // ES6 的寫法
  4. Math.max(...[14, 3, 77])  
  5. //  等同於
  6. Math.max(14, 3, 77);  
上面程式碼表示,由於 JavaScript 不提供求陣列最大元素的函式,所以只能套用Math.max函式,將陣列轉為一個引數序列,然後求最大值。有了擴充套件運算子以後,就可以直接用Math.max了。

另一個例子是通過push函式,將一個數組新增到另一個數組的尾部。

[javascript] view plain copy 在CODE上檢視程式碼片派生到我的程式碼片
  1. // ES5 的寫法
  2. var arr1 = [0, 1, 2];  
  3. var arr2 = [3, 4, 5];  
  4. Array.prototype.push.apply(arr1, arr2);  
  5. // ES6 的寫法
  6. var arr1 = [0, 1, 2];  
  7. var arr2 = [3, 4, 5];  
  8. arr1.push(...arr2);  

上面程式碼的 ES5 寫法中,push方法的引數不能是陣列,所以只好通過apply方法變通使用push方法。有了擴充套件運算子,就可以直接將陣列傳入push方法。
下面是另外一個例子。

[javascript] view plain copy 在CODE上檢視程式碼片派生到我的程式碼片
  1. // ES5
  2. new (Date.bind.apply(Date, [null, 2015, 1, 1]))  
  3. // ES6
  4. new Date(...[2015, 1, 1]);  
3  擴充套件運算子的應用

( 1 )合併陣列

擴充套件運算子提供了數組合並的新寫法。

[javascript] view plain copy 在CODE上檢視程式碼片派生到我的程式碼片
  1. // ES5
  2. [1, 2].concat(more)  
  3. // ES6
  4. [1, 2, ...more]  
  5. var arr1 = ['a''b'];  
  6. var arr2 = ['c'];  
  7. var arr3 = ['d''e'];  
  8. // ES5 的合併陣列
  9. arr1.concat(arr2, arr3);  
  10. // [ 'a', 'b', 'c', 'd', 'e' ]
  11. // ES6 的合併陣列
  12. [...arr1, ...arr2, ...arr3]  
  13. // [ 'a', 'b', 'c', 'd', 'e' ]
( 2 )與解構賦值結合

擴充套件運算子可以與解構賦值結合起來,用於生成陣列。

[javascript] view plain copy 在CODE上檢視程式碼片派生到我的程式碼片
  1. // ES5
  2. a = list[0], rest = list.slice(1)  
  3. // ES6
  4. [a, ...rest] = list  
  5. 下面是另外一些例子。  
  6. const [first, ...rest] = [1, 2, 3, 4, 5];  
  7. first // 1
  8. rest // [2, 3, 4, 5]
  9. const [first, ...rest] = [];  
  10. first // undefined
  11. rest // []:
  12. const [first, ...rest] = ["foo"];  
  13. first // "foo"
  14. rest // []
如果將擴充套件運算子用於陣列賦值,只能放在引數的最後一位,否則會報錯。 [javascript] view plain copy 在CODE上檢視程式碼片派生到我的程式碼片
  1. const [...butLast, last] = [1, 2, 3, 4, 5];  
  2. //  報錯
  3. const [first, ...middle, last] = [1, 2, 3, 4, 5];  
  4. //  報錯

( 3 )函式的返回值

JavaScript 的函式只能返回一個值,如果需要返回多個值,只能返回陣列或物件。擴充套件運算子提供瞭解決這個問題的一種變通方法。

[javascript] view plain copy 在CODE上檢視程式碼片派生到我的程式碼片
  1. var dateFields = readDateFields(database);  
  2. var d = new Date(...dateFields);  
上面程式碼從資料庫取出一行資料,通過擴充套件運算子,直接將其傳入建構函式Date。

( 4 )字串

擴充套件運算子還可以將字串轉為真正的陣列。

[javascript] view plain copy 在CODE上檢視程式碼片派生到我的程式碼片
  1. [...'hello']  
  2. // [ "h", "e", "l", "l", "o" ]
上面的寫法,有一個重要的好處,那就是能夠正確識別 32 位的 Unicode 字元。 [javascript] view plain copy 在CODE上檢視程式碼片派生到我的程式碼片
  1. 'x\uD83D\uDE80y'.length // 4