ES6/ES2015 對 Javascript 語言進(jìn)行了重大升級骗灶。它引入了許多不同的新功能。其中之一就是我們可以用在任何兼容容器(對象系草、數(shù)組通熄、字符串、集合找都、映射)前面的三個連續(xù)點(diǎn)唇辨。這使我們能夠編寫更加優(yōu)雅和簡潔的代碼。本文將會使用最常見的例子來解釋這三個點(diǎn)
三個點(diǎn)具有兩個含義:展開運(yùn)算符(spread operator)和 剩余運(yùn)算符(rest operator)
展開運(yùn)算符
展開運(yùn)算符允許迭代器在接收器內(nèi)部分別展開或擴(kuò)展能耻。
迭代器和接收器可以是任何可以循環(huán)的對象赏枚,例如數(shù)組、對象晓猛、集合饿幅、映射等。
你可以把一個容器的每個部分分別放入另一個容器鞍帝。
const arr = ['axtlive',...anotherArr];
剩余運(yùn)算符
剩余參數(shù)語法允許我們將無限數(shù)量的參數(shù)表示為數(shù)組诫睬,命名參數(shù)的位置可以在剩余參數(shù)之前。
const func = (first,second,...rest) => {};
使用示例
數(shù)組示例
- 復(fù)制數(shù)組
當(dāng)我們需要修改一個數(shù)組帕涌,但又不想改變原數(shù)組(因?yàn)槠渌胤娇赡軙褂玫皆瓟?shù)組),因此我們必須進(jìn)行數(shù)組的復(fù)制续徽。
const arr = ['Vue','React','Angular'];
const copyArr = [...arr]; // ['Vue','React','Angular'];
console.log(arr === copyArr); // false
它可以選擇數(shù)組(arr)里面的每個元素蚓曼,并把每個元素放到新的數(shù)據(jù)結(jié)構(gòu)(copyArr)中。
當(dāng)然我們也可以使用老的數(shù)組方法 map
來實(shí)現(xiàn)數(shù)組的復(fù)制并進(jìn)行身份映射钦扭。
arr.map(item => item);
- 唯一數(shù)組
如果我們想從數(shù)組里篩選出重復(fù)的元素纫版,最簡單的解決方案是什么?
Set
對象里面存儲的都是唯一的元素客情,并且可以用數(shù)組填充其弊。同時它也具有迭代接口癞己,則我們可以把它展開到新的數(shù)組中去,得到的數(shù)組中的值就是唯一的梭伐。
const fruits = ['apple', 'orange', 'banana', 'banana'];
const uniqueFruits = [...new Set(fruits)]; // ['apple', 'orange', 'banana'];
// old way
fruits.filter((fruit, index, arr) => arr.indexOf(fruit) === index);
- 串聯(lián)數(shù)組
我們可以使用 concat
方法來連接兩個獨(dú)立的數(shù)組痹雅,那同樣的也可以使用展開運(yùn)算符呀!
const fruits = ['apple', 'orange', 'banana'];
const vegetables = ['carrot'];
const fruitsAndVegetables = [...fruits, ...vegetables]; // ['apple', 'orange', 'banana', 'carrot']
const fruitsAndVegetables = ['carrot', ...fruits]; // ['carrot', 'apple', 'orange', 'banana']
// old way
const fruitsAndVegetables = fruits.concat(vegetables);
fruits.unshift('carrot');
- 將參數(shù)作為數(shù)組進(jìn)行傳遞
當(dāng)傳遞參數(shù)時糊识,展開運(yùn)算符可以使我們的代碼更具可讀性绩社。
在 ES6 之前,我們必須把函數(shù)應(yīng)用于 arguments
赂苗。
如今我們可以把參數(shù)展開到函數(shù)中愉耙,使得代碼更加簡潔。
const mixer = (x,y,z) => console.log(x,y,z);
const fruits = ['apple', 'orange', 'banana'];
mixer(...fruits); // 'apple', 'orange', 'banana'
// old way
mixer.apply(null, fruits);
- 數(shù)組切割
如果有需要拌滋,使用展開運(yùn)算符可以實(shí)現(xiàn)數(shù)組的切割朴沿,但是必須一個個的去命名剩余的元素,如果數(shù)組過大败砂,這并不是一個好的方式赌渣。
使用 slice
方法切割更加直接。
const fruits = ['apple', 'orange', 'banana'];
const [apple, ...remainingFruits] = fruits; // ['orange', 'banana']
// old way
const remainingFruits = fruits.slice(1);
- 將參數(shù)轉(zhuǎn)換為數(shù)組
Javascript 中的參數(shù)是類似數(shù)組的對象吠卷。
你可以用索引來訪問它锡垄,但是不能調(diào)用像 map
、filter
這樣的數(shù)組方法祭隔。
參數(shù)是一個可迭代的對象货岭,那么我們做些什么呢?在它們前面放三個點(diǎn)疾渴,然后作為數(shù)組去訪問千贯!
const func = (...args) => console.log(args);
func('React'); // ['React'];
- 將 NodeList 轉(zhuǎn)換為數(shù)組
參數(shù)就像從 querySelectorAll
函數(shù)返回的 NodeList
一樣。
它們的行為也有點(diǎn)像數(shù)組搞坝,只是沒有對應(yīng)的方法搔谴。
[...document.querySelectorAll('div')];
// old way
Array.prototype.slice.call(document.querySelectorAll('div'));
對象示例
- 復(fù)制對象
復(fù)制對象和復(fù)制數(shù)組的工作方式相同。
在這之前你也可以使用 Object.assign
和一個空對象來實(shí)現(xiàn)對象的復(fù)制桩撮。
const info = {name:'axtlive'};
const copyInfo = {...info}; // {name:'axtlive'}
console.log(info = copyInfo); // false
// old way
const copyInfo = Object.assign({},info)
- 合并對象
合并的唯一區(qū)別是具有相同鍵的屬性將被覆蓋敦第。
最右邊的屬性具有最高優(yōu)先級。
const info1 = {name:'axtlive'};
const info2 = {age:23};
const info3 = {look:'cool'};
const infoOfMe = {...info1,...info2,...info3}; // {name:'axtlive',age:23,look:'cool'}
// old way
Object.assigin({},info1,info2,info3);
字符串示例
- 將字符串拆分成字符
你可以用展開運(yùn)算符把字符串拆分為字符店量。
當(dāng)然芜果,如果你用空字符串調(diào)用 split
方法也是一樣的。
const city = 'SHANGHAI';
console.log([...city]); // ['S','H','A','N','G','H','A','I']
// old way
city.split('')
總結(jié)
在本文中我們研究了 Javascript 中展開運(yùn)算符的許多用例融师。如你所見右钾,ES6 不僅使編寫代碼的效率更高,而且還引入了一些有趣的方法來解決長期存在的問題。現(xiàn)在所有主流瀏覽器都支持新語法舀射。在你閱讀本文時窘茁,就可以在瀏覽器的控制臺中嘗試上述所有例子。無論用哪種方式脆烟,你現(xiàn)在就可以把展開運(yùn)算符和剩余參數(shù)用到自己的代碼中山林。