前面的話
我們經(jīng)常定義許多對(duì)象和數(shù)組,然后有組織地從中提取相關(guān)的信息片段。在ES6中添加了可以簡(jiǎn)化這種任務(wù)的新特性:解構(gòu)。解構(gòu)是一種打破數(shù)據(jù)結(jié)構(gòu)嫂便,將其拆分為更小部分的過(guò)程。本文將詳細(xì)介紹ES6解構(gòu)賦值
引入
在ES5中闸与,開(kāi)發(fā)者們?yōu)榱藦膶?duì)象和數(shù)組中獲取特定數(shù)據(jù)并賦值給變量毙替,編寫(xiě)了許多看起來(lái)同質(zhì)化的代碼
let options = {
repeat: true,
save: false
};
// 從對(duì)象中提取數(shù)據(jù)
let repeat = options.repeat,
save = options.save;
這段代碼從options對(duì)象中提取repeat和save的值,并將其存儲(chǔ)為同名局部變量践樱,提取的過(guò)程極為相似
如果要提取更多變量厂画,則必須依次編寫(xiě)類似的代碼來(lái)為變量賦值,如果其中還包含嵌套結(jié)構(gòu)映胁,只靠遍歷是找不到真實(shí)信息的木羹,必須要深入挖掘整個(gè)數(shù)據(jù)結(jié)構(gòu)才能找到所需數(shù)據(jù)
所以ES6添加了解構(gòu)功能,將數(shù)據(jù)結(jié)構(gòu)打散的過(guò)程變得更加簡(jiǎn)單解孙,可以從打散后更小的部分中獲取所需信息
對(duì)象解構(gòu)
對(duì)象字面量的語(yǔ)法形式是在一個(gè)賦值操作符左邊放置一個(gè)對(duì)象字面量
let node = {
type: "Identifier",
name: "foo"
};
let { type, name } = node;
console.log(type); // "Identifier"
console.log(name); // "foo"
在這段代碼中坑填,node.type的值被存儲(chǔ)在名為type的變量中;node.name的值被存儲(chǔ)在名為name的變量中
【解構(gòu)賦值】
到目前為止弛姜,我們已經(jīng)將對(duì)象解構(gòu)應(yīng)用到了變量的聲明中脐瑰。然而,我們同樣可以在給變量賦值時(shí)使用解構(gòu)語(yǔ)法
let node = {
type: "Identifier",
name: "foo"
},
type = "Literal",
name = 5;
// 使用解構(gòu)來(lái)分配不同的值
({ type, name } = node);
console.log(type); // "Identifier"
console.log(name); // "foo"
在這個(gè)示例中廷臼,聲明變量type和name時(shí)初始化了一個(gè)值苍在,在后面幾行中绝页,通過(guò)解構(gòu)賦值的方法,從node對(duì)象讀取相應(yīng)的值重新為這兩個(gè)變量賦值
[注意]一定要用一對(duì)小括號(hào)包裹解構(gòu)賦值語(yǔ)句寂恬,JS引擎將一對(duì)開(kāi)放的花括號(hào)視為一個(gè)代碼塊续誉。語(yǔ)法規(guī)定,代碼塊語(yǔ)句不允許出現(xiàn)在賦值語(yǔ)句左側(cè)初肉,添加小括號(hào)后可以將塊語(yǔ)句轉(zhuǎn)化為一個(gè)表達(dá)式酷鸦,從而實(shí)現(xiàn)整個(gè)解構(gòu)賦值過(guò)程
解構(gòu)賦值表達(dá)式的值與表達(dá)式右側(cè)(也就是=右側(cè))的值相等,如此一來(lái)牙咏,在任何可以使用值的地方都可以使用解構(gòu)賦值表達(dá)式
let node = {
type: "Identifier",
name: "foo"
},
type = "Literal",
name = 5;
function outputInfo(value) {
console.log(value === node); // true
}
outputInfo({ type, name } = node);
console.log(type); // "Identifier"
console.log(name); // "foo"
調(diào)用outputlnfo()函數(shù)時(shí)傳入了一個(gè)解構(gòu)表達(dá)式臼隔,由于JS表達(dá)式的值為右側(cè)的值,因而此處傳入的參數(shù)等同于node妄壶,且變量type和name被重新賦值摔握,最終將node傳入outputlnfo()函數(shù)
[注意]解構(gòu)賦值表達(dá)式(也就是=右側(cè)的表達(dá)式)如果為null或undefined會(huì)導(dǎo)致程序拋出錯(cuò)誤。也就是說(shuō)丁寄,任何嘗試讀取null或undefined的屬性的行為都會(huì)觸發(fā)運(yùn)行時(shí)錯(cuò)誤
【默認(rèn)值】
使用解構(gòu)賦值表達(dá)式時(shí)氨淌,如果指定的局部變量名稱在對(duì)象中不存在,那么這個(gè)局部變量會(huì)被賦值為undefined
let node = {
type: "Identifier",
name: "foo"
};
let { type, name, value } = node;
console.log(type); // "Identifier"
console.log(name); // "foo"
console.log(value); // undefined
這段代碼額外定義了一個(gè)局部變量value狡逢,然后嘗試為它賦值宁舰,然而在node對(duì)象上,沒(méi)有對(duì)應(yīng)名稱的屬性值奢浑,所以像預(yù)期中的那樣將它賦值為undefined
當(dāng)指定的屬性不存在時(shí)蛮艰,可以隨意定義一個(gè)默認(rèn)值,在屬性名稱后添加一個(gè)等號(hào)(=)和相應(yīng)的默認(rèn)值即可
let node = {
type: "Identifier",
name: "foo"
};
let { type, name, value = true } = node;
console.log(type); // "Identifier"
console.log(name); // "foo"
console.log(value); // true
在此示例中雀彼,為變量value設(shè)置了默認(rèn)值true壤蚜,只有當(dāng)node上沒(méi)有該屬性或者該屬性值為undefined時(shí)該值才生效。此處沒(méi)有node.value屬性徊哑,因?yàn)関alue使用了預(yù)設(shè)的默認(rèn)值
【為非同名局部變量賦值】
如果希望使用不同命名的局部變量來(lái)存儲(chǔ)對(duì)象屬性的值袜刷,ES6中的一個(gè)擴(kuò)展語(yǔ)法可以滿足需求,這個(gè)語(yǔ)法與完整的對(duì)象字面量屬性初始化程序的很像
let node = {
type: "Identifier",
name: "foo"
};
let { type: localType, name: localName } = node;
console.log(localType); // "Identifier"
console.log(localName); // "foo"
這段代碼使用了解構(gòu)賦值來(lái)聲明變量localType和localName莺丑,這兩個(gè)變量分別包含node.type和node.name屬性的值著蟹。type:localType語(yǔ)法的含義是讀取名為type的屬性并將其值存儲(chǔ)在變量localType中,這種語(yǔ)法實(shí)際上與傳統(tǒng)對(duì)象字面量的語(yǔ)法相悖梢莽,原來(lái)的語(yǔ)法名稱在冒號(hào)左邊萧豆,值在右邊;現(xiàn)在值在冒號(hào)右邊昏名,而對(duì)象的屬性名在左邊
當(dāng)使用其他變量名進(jìn)行賦值時(shí)也可以添加默認(rèn)值涮雷,只需在變量名后添加等號(hào)和默認(rèn)值即可
let node = {
type: "Identifier"
};
let { type: localType, name: localName = "bar" } = node;
console.log(localType); // "Identifier"
console.log(localName); // "bar"
在這段代碼中,由于node.name屬性不存在轻局,變量被默認(rèn)賦值為"bar"
【嵌套對(duì)象解構(gòu)】
解構(gòu)嵌套對(duì)象仍然與對(duì)象字面量的語(yǔ)法相似洪鸭,可以將對(duì)象拆解以獲取想要的信息
let node = {
type: "Identifier",
name: "foo",
loc: {
start: {
line: 1,
column: 1
},
end: {
line: 1,
column: 4
}
}
};
let { loc: { start }} = node;
console.log(start.line); // 1
console.log(start.column); // 1
在這個(gè)示例中样刷,我們?cè)诮鈽?gòu)模式中使用了花括號(hào),其含義為在找到node對(duì)象中的loc屬性后览爵,應(yīng)當(dāng)深入一層繼續(xù)查找start屬性置鼻。在上面的解構(gòu)示例中,所有冒號(hào)前的標(biāo)識(shí)符都代表在對(duì)象中的檢索位置拾枣,其右側(cè)為被賦值的變量名沃疮;如果冒號(hào)后是花括號(hào)盒让,則意味著要賦予的最終值嵌套在對(duì)象內(nèi)部更深的層級(jí)中
更進(jìn)一步梅肤,也可以使用一個(gè)與對(duì)象屬性名不同的局部變量名
let node = {
type: "Identifier",
name: "foo",
loc: {
start: {
line: 1,
column: 1
},
end: {
line: 1,
column: 4
}
}
};
// 提取 node.loc.start
let { loc: { start: localStart }} = node;
console.log(localStart.line); // 1
console.log(localStart.column); // 1
在這個(gè)版本中,node.loc.start被存儲(chǔ)在了新的局部變量localStart中邑茄。解構(gòu)模式可以應(yīng)用于任意層級(jí)深度的對(duì)象姨蝴,且每一層都具備同等的功能
數(shù)組解構(gòu)
與對(duì)象解構(gòu)的語(yǔ)法相比,數(shù)組解構(gòu)就簡(jiǎn)單多了肺缕,它使用的是數(shù)組字面量左医,且解構(gòu)操作全部在數(shù)組內(nèi)完成,而不是像對(duì)象字面量語(yǔ)法一樣使用對(duì)象的命名屬性
let colors = [ "red", "green", "blue" ];
let [ firstColor, secondColor ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
在這段代碼中同木,我們從colors數(shù)組中解構(gòu)出了"red"和"green"這兩個(gè)值浮梢,并分別存儲(chǔ)在變量firstColor和變量secondColor中。在數(shù)組解構(gòu)語(yǔ)法中彤路,我們通過(guò)值在數(shù)組中的位置進(jìn)行選取秕硝,且可以將其存儲(chǔ)在任意變量中,未顯式聲明的元素都會(huì)直接被忽略
在解構(gòu)模式中洲尊,也可以直接省略元素远豺,只為感興趣的元素提供變量名
let colors = [ "red", "green", "blue" ];
let [ , , thirdColor ] = colors;
console.log(thirdColor); // "blue"
這段代碼使用解構(gòu)賦值語(yǔ)法從colors中獲取第3個(gè)元素,thirdColor前的逗號(hào)是前方元素的占位符坞嘀,無(wú)論數(shù)組中的元素有多少個(gè)躯护,都可以通過(guò)這種方法提取想要的元素,不需要為每一個(gè)元素都指定變量名
【解構(gòu)賦值】
數(shù)組解構(gòu)也可用于賦值上下文丽涩,但不需要用小括號(hào)包裹表達(dá)式棺滞,這一點(diǎn)與對(duì)象解構(gòu)不同
let colors = [ "red", "green", "blue" ],
firstColor = "black",
secondColor = "purple";
[ firstColor, secondColor ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
這段代碼中的解構(gòu)賦值與上一個(gè)數(shù)組解構(gòu)示例相差無(wú)幾,唯一的區(qū)別是此處的firstColor變量和secondColor變量已經(jīng)被定義了
【變量交換】
數(shù)組解構(gòu)語(yǔ)法還有一個(gè)獨(dú)特的用例:交換兩個(gè)變量的值矢渊。在排序算法中继准,值交換是一個(gè)非常常見(jiàn)的操作,如果要在ES5中交換兩個(gè)變量的值昆淡,則須引入第三個(gè)臨時(shí)變量
[](javascript:void(0); "復(fù)制代碼")
let a = 1,
b = 2,
tmp;
tmp = a;
a = b;
b = tmp;
console.log(a); // 2
console.log(b); // 1
在這種變量交換的方式中锰瘸,中間變量tmp不可或缺。如果使用數(shù)組解構(gòu)賦值語(yǔ)法昂灵,就不再需要額外的變量了
// 在 ES6 中互換值
let a = 1,
b = 2;
[ a, b ] = [ b, a ];
console.log(a); // 2
console.log(b); // 1
在這個(gè)示例中避凝,數(shù)組解構(gòu)賦值看起來(lái)像是一個(gè)鏡像:賦值語(yǔ)句左側(cè)(也就是等號(hào)左側(cè))與其他數(shù)組解構(gòu)示例一樣舞萄,是一個(gè)解構(gòu)模式;右側(cè)是一個(gè)為交換過(guò)程創(chuàng)建的臨時(shí)數(shù)組字面量管削。代碼執(zhí)行過(guò)程中倒脓,先解構(gòu)臨時(shí)數(shù)組,將b和a的值復(fù)制到左側(cè)數(shù)組的前兩個(gè)位置含思,最終結(jié)果是變量互換了它們的值
[注意]如果右側(cè)數(shù)組解構(gòu)賦值表達(dá)式的值為null或undefined崎弃,則會(huì)導(dǎo)致程序拋出錯(cuò)誤
【默認(rèn)值】
也可以在數(shù)組解構(gòu)賦值表達(dá)式中為數(shù)組中的任意位置添加默認(rèn)值,當(dāng)指定位置的屬性不存在或其值為undefined時(shí)使用默認(rèn)值
let colors = [ "red" ];
let [ firstColor, secondColor = "green" ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
在這段代碼中含潘,colors數(shù)組中只有一個(gè)元素饲做,secondColor沒(méi)有對(duì)應(yīng)的匹配值,但是它有一個(gè)默認(rèn)值"green"遏弱,所以最終secondColor的輸出結(jié)果不會(huì)是undefined
【嵌套數(shù)組解構(gòu)】
嵌套數(shù)組解構(gòu)與嵌套對(duì)象解構(gòu)的語(yǔ)法類似盆均,在原有的數(shù)組模式中插入另一個(gè)數(shù)組模式,即可將解構(gòu)過(guò)程深入到下一個(gè)層級(jí)
let colors = [ "red", [ "green", "lightgreen" ], "blue" ]; // 隨后
let [ firstColor, [ secondColor ] ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
在此示例中漱逸,變量secondColor引用的是colors數(shù)組中的值"green"泪姨,該元素包含在數(shù)組內(nèi)部的另一個(gè)數(shù)組中,所以seconColor兩側(cè)的方括號(hào)是一個(gè)必要的解構(gòu)模式饰抒。同樣肮砾,在數(shù)組中也可以無(wú)限深入去解構(gòu),就像在對(duì)象中一樣
【不定元素】
函數(shù)具有不定參數(shù)袋坑,而在數(shù)組解構(gòu)語(yǔ)法中有一個(gè)相似的概念——不定元素仗处。在數(shù)組中,可以通過(guò)...語(yǔ)法將數(shù)組中的其余元素賦值給一個(gè)特定的變量
let colors = [ "red", "green", "blue" ];
let [ firstColor, ...restColors ] = colors;
console.log(firstColor); // "red"
console.log(restColors.length); // 2
console.log(restColors[0]); // "green"
console.log(restColors[1]); // "blue"
數(shù)組colors中的第一個(gè)元素被賦值給了firstColor咒彤,其余的元素被賦值給restColors數(shù)組疆柔,所以restColors中包含兩個(gè)元素:"green"和"blue"。不定元素語(yǔ)法有助于從數(shù)組中提取特定元素并保證其余元素可用
【數(shù)組復(fù)制】
在ES5中镶柱,開(kāi)發(fā)者們經(jīng)常使用concat()方法來(lái)克隆數(shù)組
// 在 ES5 中克隆數(shù)組
var colors = [ "red", "green", "blue" ]; var clonedColors = colors.concat();
console.log(clonedColors); //"[red,green,blue]
concat()方法的設(shè)計(jì)初衷是連接兩個(gè)數(shù)組旷档,如果調(diào)用時(shí)不傳遞參數(shù)就會(huì)返回當(dāng)前函數(shù)的副本
在ES6中,可以通過(guò)不定元素的語(yǔ)法來(lái)實(shí)現(xiàn)相同的目標(biāo)
// 在 ES6 中克隆數(shù)組
let colors = [ "red", "green", "blue" ];
let [ ...clonedColors ] = colors;
console.log(clonedColors); //"[red,green,blue]
在這個(gè)示例中歇拆,我們通過(guò)不定元素的語(yǔ)法將colors數(shù)組中的值復(fù)制到clonedColors數(shù)組中
[注意]在被解構(gòu)的數(shù)組中鞋屈,不定元素必須為最后一個(gè)條目,在后面繼續(xù)添加逗號(hào)會(huì)導(dǎo)致程序拋出語(yǔ)法錯(cuò)誤
混合解構(gòu)
可以混合使用對(duì)象解構(gòu)和數(shù)組解構(gòu)來(lái)創(chuàng)建更多復(fù)雜的表達(dá)式故觅,如此一來(lái)厂庇,可以從任何混雜著對(duì)象和數(shù)組的數(shù)據(jù)解構(gòu)中提取想要的信息
let node = {
type: "Identifier",
name: "foo",
loc: {
start: {
line: 1,
column: 1 },
end: {
line: 1,
column: 4 }
},
range: [0, 3]
};
let {
loc: { start },
range: [ startIndex ]
} = node;
console.log(start.line); // 1
console.log(start.column); // 1
console.log(startIndex); // 0
這段代碼分別將node.loc.start和node.range[0]提取到變量start和startlndex中
解構(gòu)模式中的loc和range僅代表它們?cè)趎ode對(duì)象中所處的位置(也就是該對(duì)象的屬性)。當(dāng)使用混合解構(gòu)的語(yǔ)法時(shí)输吏,則可以從node提取任意想要的信息权旷。這種方法極為有效,尤其是從JSON配置中提取信息時(shí)贯溅,不再需要遍歷整個(gè)結(jié)構(gòu)了
【解構(gòu)參數(shù)】
解構(gòu)可以用在函數(shù)參數(shù)的傳遞過(guò)程中拄氯,這種使用方式更特別躲查。當(dāng)定義一個(gè)接受大量可選參數(shù)的JS函數(shù)時(shí),通常會(huì)創(chuàng)建一個(gè)可選對(duì)象译柏,將額外的參數(shù)定義為這個(gè)對(duì)象的屬性
// options 上的屬性表示附加參數(shù)
function setCookie(name, value, options) {
options = options || {};
let secure = options.secure,
path = options.path,
domain = options.domain,
expires = options.expires; // 設(shè)置 cookie 的代碼
} // 第三個(gè)參數(shù)映射到 options
setCookie("type", "js", {
secure: true,
expires: 60000 });
許多JS庫(kù)中都有類似的setCookie()函數(shù)镣煮,而在示例函數(shù)中,name和value是必需參數(shù)鄙麦,而secure典唇、path、domain和expires則不然胯府,這些參數(shù)相對(duì)而言沒(méi)有優(yōu)先級(jí)順序介衔,將它們列為額外的命名參數(shù)也不合適,此時(shí)為options對(duì)象設(shè)置同名的命名屬性是一個(gè)很好的選擇∶私伲現(xiàn)在的問(wèn)題是夜牡,僅查看函數(shù)的聲明部分,無(wú)法辨識(shí)函數(shù)的預(yù)期參數(shù)侣签,必須通過(guò)閱讀函數(shù)體才可以確定所有參數(shù)的情況
如果將options定義為解構(gòu)參數(shù),則可以更清晰地了解函數(shù)預(yù)期傳入的參數(shù)急迂。解構(gòu)參數(shù)需要使用對(duì)象或數(shù)組解構(gòu)模式代替命名參數(shù)
[](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; white-space: pre-wrap; word-wrap: break-word; padding: 0px; list-style-type: none; list-style-image: none; font-family: "Courier New" !important; font-size: 12px !important;">function setCookie(name, value, { secure, path, domain, expires }) { // 設(shè)置 cookie 的代碼
}
setCookie("type", "js", {
secure: true,
expires: 60000 });</pre>
](javascript:void(0); "復(fù)制代碼")
這個(gè)函數(shù)與之前示例中的函數(shù)具有相似的特性影所,只是現(xiàn)在使用解構(gòu)語(yǔ)法代替了第3個(gè)參數(shù)來(lái)提取必要的信息,其他參數(shù)保持不變僚碎,但是對(duì)于調(diào)用setCookie()函數(shù)的使用者而言猴娩,解構(gòu)參數(shù)變得更清晰了
【必須傳值的解構(gòu)參數(shù)】
解構(gòu)參數(shù)有一個(gè)奇怪的地方,默認(rèn)情況下勺阐,如果調(diào)用函數(shù)時(shí)不提供被解構(gòu)的參數(shù)會(huì)導(dǎo)致程序拋出錯(cuò)誤
<pre style="margin: 0px; white-space: pre-wrap; word-wrap: break-word; padding: 0px; list-style-type: none; list-style-image: none; font-family: "Courier New" !important; font-size: 12px !important;">// 出錯(cuò)卷中!
setCookie("type", "js");</pre>
缺失的第3個(gè)參數(shù),其值為undefined渊抽,而解構(gòu)參數(shù)只是將解構(gòu)聲明應(yīng)用在函數(shù)參數(shù)的一個(gè)簡(jiǎn)寫(xiě)方法蟆豫,其會(huì)導(dǎo)致程序拋出錯(cuò)誤。當(dāng)調(diào)用setCookie()函數(shù)時(shí)懒闷,JS引擎實(shí)際上做了以下這些事情
<pre style="margin: 0px; white-space: pre-wrap; word-wrap: break-word; padding: 0px; list-style-type: none; list-style-image: none; font-family: "Courier New" !important; font-size: 12px !important;">function setCookie(name, value, options) {
let { secure, path, domain, expires } = options; // 設(shè)置 cookie 的代碼
}</pre>
如果解構(gòu)賦值表達(dá)式的右值為null或undefined十减,則程序會(huì)報(bào)錯(cuò)。同理愤估,若調(diào)用setCookie()函數(shù)時(shí)不傳入第3個(gè)參數(shù)帮辟,也會(huì)導(dǎo)致程序拋出錯(cuò)誤
如果解構(gòu)參數(shù)是必需的,大可忽略掉這些問(wèn)題玩焰;但如果希望將解構(gòu)參數(shù)定義為可選的由驹,那么就必須為其提供默認(rèn)值來(lái)解決這個(gè)問(wèn)題
<pre style="margin: 0px; white-space: pre-wrap; word-wrap: break-word; padding: 0px; list-style-type: none; list-style-image: none; font-family: "Courier New" !important; font-size: 12px !important;">function setCookie(name, value, { secure, path, domain, expires } = {}) { // ...
}</pre>
這個(gè)示例中為解構(gòu)參數(shù)添加了一個(gè)新對(duì)象作為默認(rèn)值,secure昔园、path蔓榄、domain及expires這些變量的值全部為undefined闹炉,這樣即使在調(diào)用setCookie()時(shí)未傳遞第3個(gè)參數(shù),程序也不會(huì)報(bào)錯(cuò)
【默認(rèn)值】
可以為解構(gòu)參數(shù)指定默認(rèn)值润樱,就像在解構(gòu)賦值語(yǔ)句中那樣渣触,只需在參數(shù)后添加等號(hào)并且指定一個(gè)默認(rèn)值即可
[](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; white-space: pre-wrap; word-wrap: break-word; padding: 0px; list-style-type: none; list-style-image: none; font-family: "Courier New" !important; font-size: 12px !important;">function setCookie(name, value,
{
secure = false,
path = "/",
domain = "example.com",
expires = new Date(Date.now() + 360000000)
} = {}
) { // ...
}</pre>
](javascript:void(0); "復(fù)制代碼")
在這段代碼中,解構(gòu)參數(shù)的每一個(gè)屬性都有默認(rèn)值壹若,從而無(wú)須再逐一檢查每一個(gè)屬性是否都有默認(rèn)值嗅钻。然而,這種方法也有很多缺點(diǎn)店展。首先养篓,函數(shù)聲明變得比以前復(fù)雜了;其次赂蕴,如果解構(gòu)參數(shù)是可選的柳弄,那么仍然要給它添加一個(gè)空對(duì)象作為參數(shù),否則像setCookie("type","js")這樣的調(diào)用會(huì)導(dǎo)致程序拋出錯(cuò)誤
對(duì)于對(duì)象類型的解構(gòu)參數(shù)概说,最好為其賦予相同解構(gòu)的默認(rèn)參數(shù)
[](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; white-space: pre-wrap; word-wrap: break-word; padding: 0px; list-style-type: none; list-style-image: none; font-family: "Courier New" !important; font-size: 12px !important;">function setCookie(name, value,
{
secure = false,
path = "/",
domain = "example.com",
expires = new Date(Date.now() + 360000000)
} = {
secure : false,
path : "/",
domain : "example.com",
expires : new Date(Date.now() + 360000000)
}
) { // ...
}</pre>
](javascript:void(0); "復(fù)制代碼")
現(xiàn)在函數(shù)變得更加完整了碧注,第一個(gè)對(duì)象字面量是解構(gòu)參數(shù),第二個(gè)為默認(rèn)值糖赔。但是這會(huì)造成非常多的代碼冗余萍丐,可以將默認(rèn)值提取到一個(gè)獨(dú)立對(duì)象中,并且使用該對(duì)象作為解構(gòu)和默認(rèn)參數(shù)的一部分放典,從而消除這些冗余
[](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; white-space: pre-wrap; word-wrap: break-word; padding: 0px; list-style-type: none; list-style-image: none; font-family: "Courier New" !important; font-size: 12px !important;">const setCookieDefaults = {
secure : false,
path : "/",
domain : "example.com",
expires : new Date(Date.now() + 360000000)
} function setCookie(name, value,{
secure = setCookieDefaults.secure,
path = setCookieDefaults.path,
domain = setCookieDefaults.domain,
expires = setCookieDefaults.expires
}=setCookieDefaults) { // ...
}</pre>
](javascript:void(0); "復(fù)制代碼")
在這段代碼中逝变,默認(rèn)值已經(jīng)被放到setCookieDefaults對(duì)象中,除了作為默認(rèn)參數(shù)值外奋构,在解構(gòu)參數(shù)中可以直接使用這個(gè)對(duì)象來(lái)為每一個(gè)綁定設(shè)置默認(rèn)參數(shù)壳影。使用解構(gòu)參數(shù)后,不得不面對(duì)處理默認(rèn)參數(shù)的復(fù)雜邏輯弥臼,但它也有好的一面宴咧,如果要改變默認(rèn)值,可以立即在setCookieDefaults中修改醋火,改變的數(shù)據(jù)將自動(dòng)同步到所有出現(xiàn)過(guò)的地方
其他解構(gòu)
【字符串解構(gòu)】
字符串也可以解構(gòu)賦值悠汽。這是因?yàn)椋址晦D(zhuǎn)換成了一個(gè)類似數(shù)組的對(duì)象
[](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; white-space: pre-wrap; word-wrap: break-word; padding: 0px; list-style-type: none; list-style-image: none; font-family: "Courier New" !important; font-size: 12px !important;">const [a, b, c, d, e] = 'hello';
console.log(a);//"h"
console.log(b);//"e"
console.log(c);//"l"
console.log(d);//"l"
console.log(e);//"o"</pre>
](javascript:void(0); "復(fù)制代碼")
類似數(shù)組的對(duì)象都有一個(gè)length
屬性芥驳,因此還可以對(duì)這個(gè)屬性解構(gòu)賦值
<pre style="margin: 0px; white-space: pre-wrap; word-wrap: break-word; padding: 0px; list-style-type: none; list-style-image: none; font-family: "Courier New" !important; font-size: 12px !important;">const {length} = 'hello';
console.log(length);//5</pre>
【數(shù)值和布爾值解構(gòu)】
解構(gòu)賦值時(shí)柿冲,如果等號(hào)右邊是數(shù)值和布爾值,則會(huì)先轉(zhuǎn)為對(duì)象
<pre style="margin: 0px; white-space: pre-wrap; word-wrap: break-word; padding: 0px; list-style-type: none; list-style-image: none; font-family: "Courier New" !important; font-size: 12px !important;">let {toString:s1} = 123;
console.log(s1 === Number.prototype.toString);//true
let {toString:s2} = true;
console.log(s2 === Boolean.prototype.toString);//true</pre>
解構(gòu)賦值的規(guī)則是兆旬,只要等號(hào)右邊的值不是對(duì)象或數(shù)組假抄,就先將其轉(zhuǎn)為對(duì)象。由于undefined
和null
無(wú)法轉(zhuǎn)為對(duì)象,所以對(duì)它們進(jìn)行解構(gòu)賦值宿饱,都會(huì)報(bào)錯(cuò)
<pre style="margin: 0px; white-space: pre-wrap; word-wrap: break-word; padding: 0px; list-style-type: none; list-style-image: none; font-family: "Courier New" !important; font-size: 12px !important;">let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError</pre>