ES6—擴展運算符和rest運算符(6)

1、擴展運算符簡介

擴展運算符( spread )是三個點(...),可以將一個數組轉爲用逗號分隔的參數序列。

說的通俗易懂點,有點像化骨綿掌,把一個大元素給打散成一個個單獨的小元素。

圖片描述
基本用法:拆解字符串與數組

var array = [1,2,3,4];
console.log(...array);//1 2 3 4 
var str = "String";
console.log(...str);//S t r i n g

2、擴展運算符應用

2.1 某些場景可以替代apply

在使用Math.max()求數組的最大值時,ES5可以通過 apply 做到(用一種不友好且繁瑣的方式)

// ES5 apply 寫法
var array = [1,2,3,4,3];
var max1 = Math.max.apply(null,array);
console.log(max1);//4

幸運的是JavaScript的世界在不斷改變,擴展運算符可用於數組的析構,優雅的解決了這個問題。

// ES6 擴展運算符 寫法
var array = [1,2,3,4,3];
var max2 = Math.max(...array);  
console.log(max2);//4

先把 array 打散成 1 2 3 4 3,再在裏面找最大的那一個,就顯而易見了。

2.2 代替數組的push、concat 等方法

實現把 arr2 塞到 arr1 中

// ES5 apply 寫法
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
Array.prototype.push.apply(arr1, arr2);
//arr1     [0, 1, 2, 3, 4, 5]

擴展運算符又要施展化骨大法了

// ES6 擴展運算符 寫法
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1.push(...arr2);
//arr1     [0, 1, 2, 3, 4, 5]

通俗的解釋下, 擴展運算符先把 arr2 打散成 3 4 5 , 之後再往arr1裏push,就輕鬆多了。

同理可推,concat 合併數組的時候:

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

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

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

ES5的合併數組寫法,像是 arr1 把 arr2,arr3 給吸收了。

而ES6的合併數組寫法,則是先把 arr1,arr2, arr3 拆解,之後塞到新的數組中。

2.3 拷貝數組或對象

//拷貝數組
var array0 = [1,2,3];
var array1 = [...array0];
console.log(array1);//[1, 2, 3]

//拷貝數組
var obj = {
    age:1,
    name:"lis",
    arr:{
        a1:[1,2]
    }
}
var obj2  = {...obj};
console.log(obj2);//{age: 1, name: "lis", arr: {…}}

無論是像克隆數組還是對象,先用化骨綿掌之擴展運算符,將其打散,之後再拼裝的到一起就可以了,多麼簡單易用。
圖片描述

2.4 將僞數組轉化爲數組

//僞數組轉換爲數組
var nodeList = document.querySelectorAll('div');
console.log([...nodeList]);  // [div, div, div ... ]

上面代碼中,querySelectorAll 方法返回的是一個 nodeList 對象。它不是數組,而是一個類似數組的對象。這時,擴展運算符可以將其轉爲真正的數組,原因就在於 NodeList 對象實現了 Iterator。

注意:使用擴展運算符將僞數組轉換爲數組有侷限性,這個類數組必須得有默認的迭代器且僞可遍歷的。

3、rest 運算符簡介

剩餘運算符(the rest operator),它的樣子看起來和展開操作符一樣,但是它是用於解構數組和對象。在某種程度上,剩餘元素和展開元素相反,展開元素會“展開”數組變成多個元素,剩餘元素會收集多個元素和“壓縮”成一個單一的元素。

說的通俗點,有點像吸星大法,收集多個元素,壓縮成單一的元素 。
圖片描述

rest參數用於獲取函數的多餘參數,這樣就不需要使用arguments對象了。rest參數搭配的變量是一個數組,該變量將多餘的參數放入數組中。

例如實現計算傳入所有參數的和使用arguments參數:

function sumArgu () {
     var result = 0;
     for (var i = 0; i < arguments.length; i++) {
        result += arguments[i];
    }
    return result
}
console.log(sumArgu(1,2,3));//6

使用rest參數:

function sumRest (...m) {
    var total = 0; 
    for(var i of m){
        total += i;
    }
    return total;
}
console.log(sumRest(1,2,3));//6

上面代碼利用 rest 參數,可以向該函數傳入任意數目的參數。傳遞給 sumRest 函數的一組參數值,被整合成了數組 m。

就像是吸星大法,把分散的元素收集到一起。

所以在某些場景中,無需將arguments轉爲真正的數組,可以直接使用rest參數代替。

4、rest 運算符應用

4.1 rest 參數代替arguments變量

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

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

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

不過,rest參數和arguments對象有一定的區別:

clipboard.png

4.2 與解構賦值組合使用

var array = [1,2,3,4,5,6];
var [a,b,...c] = array;
console.log(a);//1
console.log(b);//2
console.log(c);//[3, 4, 5, 6]

備註:rest參數可理解爲剩餘的參數,所以必須在最後一位定義,如果定義在中間會報錯。

var array = [1,2,3,4,5,6];
var [a,b,...c,d,e] = array;
//  Uncaught SyntaxError: Rest element must be last element

5、總結

5.1 擴展運算符和rest運算符是逆運算

擴展運算符:數組=>分割序列

rest運算符:分割序列=>數組

圖片描述
5.2 擴展運算符應用場景

由於其繁瑣的語法,apply 方法使用起來並不是很方便。當需要拿一個數組的元素作爲函數調用的參數時,擴展運算符是一個不錯的選擇。

擴展運算符還改善了數組字面量的操作,你可以更方便的初始化、連接、複製數組了。

使用析構賦值你可以提取數組的一部分。通過與迭代器協議的組合,你可以以一種更靈活的方式使用該表達式。

5.3 rest運算符應用場景

rest運算符主要是處理不定數量參數,rest參數使得收集參數變得非常簡單。它是類數組對象arguments一個合理的替代品。

rest參數還可以與解構賦值組合使用。

在實際項目中靈活應用擴展運算符、rest運算符,能寫出更精簡、易讀性高的代碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章