擴展運算符容許一個表達式在指望多個參數(用於函數調用)或多個元素(用於數組字面量)或多個變量(用於解構賦值)的位置擴展。shell
例子一:數組
let a = [1,2,3,4,5,7,3]
console.log(a); //[ 1, 2, 3, 4, 5, 7, 3 ]
console.log(...a); // 1, 2, 3, 4, 5, 7, 3
複製代碼
等同於數據結構
console.log(1,2,3,4,5,7,3); // 1, 2, 3, 4, 5, 7, 3
複製代碼
也就是說擴展運算符幫咱們把這個數組在這裏幫咱們展開了,再看一個例子函數
例子二:學習
let a = [1,2,3]
let b = [1,4]
let c = [...a,...b]
console.log(c); // [1,2,3,1,4]
複製代碼
等同於測試
let c = [1,2,3,1,4]
複製代碼
可使用擴展運算符複製,拼接數組this
let a = [1,2,3]
let b = [2,4]
let c = [...a]
let d = [...a,...b,...c]
複製代碼
再來看對象的擴展運算符使用,對象也是有子元素的,也可使用擴展運算符擴展spa
例子一3d
let obj1 = {
"name" : "cys",
"age" : 18,
"sex" : "man"
}
let obj2 = {
"name" : "cysg",
"age" : 19
}
let obj3 = {
...obj1,
...obj2
}
console.log(obj3); //{ name: 'cysg', age: 19, sex: 'man' }
複製代碼
obj,obj2換個位置再來看code
let obj3 = {
...obj2,
...obj1
}
console.log(obj3); //{ name: 'cys', age: 18, sex: 'man' }
複製代碼
從返回的值能夠看到,obj3獲得了obj1和obj2的屬性,且在後面的會覆蓋掉前面同一屬性的值,很是簡單的實現了淺複製,在替換對象屬性也很是方便
(options)=>{
this.options = {...this.options,...options}
}
複製代碼
擴展運算符把對象的子元素進行位置擴展,若是你想把對象的元素都拿出來(單個拿出來可不行),就可使用擴展運算符,那麼拿出來給誰,怎麼使用就要好好說道說道了 咱們先來嘗試一下數組轉對象
數組擴展爲對象
let a = [1,2,3]
let b = [2,4]
let c = {
...a,
...b
}
console.log(c); // { '0': 2, '1': 4, '2': 3 }
複製代碼
擴展運算符根據數組的下標和值做爲key:value鍵值對插入對象,同對象使用擴展運算符同樣沒有任何問題,那麼對象轉化爲數組會發生什麼呢?
對象擴展爲數組
let obj1 = {
"name" : "cys",
"age" : 18,
"sex" : "man"
}
let obj2 = {
"name" : "cysg",
"age" : 19
}
let arr = [...obj1,...obj2]
console.log(arr);
複製代碼
報錯了!提示咱們obj1不是iterable,obj1是不可迭代的,那咱們能輸出...obj1嗎
console.log(...obj1);
複製代碼
也不行,報了相同的錯,對象能夠擴展爲對象,數組也能夠擴展爲對象,那對象轉數組爲何會出錯呢?根據提示,咱們嘗試給這個對象定義一個iterator
let obj1 = {
"name": "cys",
"age": 18,
"sex": "man",
[Symbol.iterator]: function () {
const self = this;
let keys = Object.keys(obj1)
let index = 0;
let len = keys.length
return {
next: function () { //實現next
if (index < len) {
return { //遍歷中
value: self[keys[index++]],
done: false //表示遍歷沒有結束,done設置爲fasle
}
} else {
return { //遍歷結束
value: undefined, //結束後,返回undefined
done: true //done設置爲true,表示遍歷結束
}
}
}
}
}
}
複製代碼
再輸出看看
console.log(...obj1); // cys 18 man
console.log([...obj1]); // [ 'cys', 18, 'man' ]
複製代碼
再看
let obj1 = {
"name": "cys",
"age": 18,
"sex": "man",
[Symbol.iterator]: function () {
const self = this;
let keys = Object.keys(obj1)
let index = 0;
let len = keys.length
return {
next: function () { //實現next
if (index < len) {
return { //遍歷中
value: self[keys[index++]] + 'hello',
done: false //表示遍歷沒有結束,done設置爲fasle
}
} else {
return { //遍歷結束
value: undefined, //結束後,返回undefined
done: true //done設置爲true,表示遍歷結束
}
}
}
}
}
}
複製代碼
再輸出看看
console.log(...obj1); // cyshello 18hello manhello
console.log([...obj1]); // [ 'cyshello', '18hello', 'manhello' ]
console.log({...obj1});
// { name: 'cys',
// age: 18,
// sex: 'man',
// [Symbol(Symbol.iterator)]: [Function: [Symbol.iterator]] }
複製代碼
能夠看到,對象轉對象並無發生改變,只是把元素都擴展了出來,而當要轉化爲一個可迭代的數據結構時,就會調用自身的迭代器方法,由此能夠得出結論當擴展運算符要擴展爲可迭代的對象時,是經過iterator進行擴展的,擴展出來的值是經過iterator.next()獲得的,若是修改next()返回的值的順序,那也會改變擴展運算符擴展出來的順序。相同類型的對象擴展只是對元素的位置進行擴展
如今咱們只討論了複雜數據類型,對象,那麼基礎數據類型可否使用擴展運算符呢?
讓咱們來試試
string
console.log(...'asdwr'); //a s d w r
複製代碼
string 類型是一個僞數組,有iterator,可使用擴展運算符
number
console.log(...1);
複製代碼
boolean
console.log(...true);
複製代碼
報錯,boolean不能使用擴展運算符
null
console.log(...null);
複製代碼
報錯,沒有iterator這個屬性
undefined
console.log(...undefined);
複製代碼
報null同樣的錯
若是把基礎數據類型用擴展運算符放在對象裏,會不會有什麼不同的事情發生呢? 來看
let a = {
...null
}
console.log(a); // {}
複製代碼
通過測試,都不會報錯,可是擴展出來的都是一個空對象。
擴展運算符能夠普遍用於對象的淺複製和多個對象的數據拼接,當要轉化爲可迭代數據結構時可設置對象的迭代器對擴展運算符擴展出來的值進行操做,基礎數據只有string可使用擴展運算符,number,boolean,null,undefined無效
若是有錯,請指正,相互學習