前言
該部分為書籍 深入理解ES6 第五章(解構(gòu): 更方便的數(shù)據(jù)訪問)筆記
解構(gòu)的作用
把數(shù)據(jù)結(jié)構(gòu)分解為更小的部分時(shí)笛质,從中提取你要的數(shù)據(jù)
對(duì)象解構(gòu)
1. 語法 -- 變量聲明
- 對(duì)象解構(gòu)語法在賦值語句的左側(cè)使用了對(duì)象字面量
let node = { type: 'Identifier', name: 'foo' }; let { type, name } = node; console.log(type); // "Identifier" console.log(name); // "foo"
當(dāng)使用解構(gòu)來配合 var 撵彻、 let 或 const 來聲明變量時(shí)奸腺,必須提供初始化器(即等號(hào)右邊的值)
// 語法錯(cuò)誤! var { type, name }; // 語法錯(cuò)誤淋肾! let { type, name }; // 語法錯(cuò)誤媒抠! const { type, name };
- 當(dāng)解構(gòu)賦值表達(dá)式的右側(cè)( = 后面的表達(dá)式)的計(jì)算結(jié)果為 null 或 undefined 時(shí),會(huì)拋出錯(cuò)誤
2. 解構(gòu)賦值 -- 先聲明變量, 在賦值
注意你必須用圓括號(hào)包裹解構(gòu)賦值語句洒敏,這是因?yàn)楸┞兜幕ɡㄌ?hào)會(huì)被解析為代碼塊語句龄恋,而塊語句不允許在賦值操作符(即等號(hào))左側(cè)出現(xiàn)。
let node = {
type: "Identifier",
name: "foo"
},
type = "Literal",
name = 5;
// 使用解構(gòu)來分配不同的值
({ type, name } = node);
3. 默認(rèn)值
指定默認(rèn)值, 可以在解構(gòu)對(duì)應(yīng)的屬性缺失凶伙、或?qū)?yīng)的屬性值為 undefined
的情況下, 該默認(rèn)值才會(huì)被使用
let node = {
type: "Identifier",
name: "foo"
};
let { type, name, value = true } = node;
4. 賦值給不同的本地變量名 -- 別名
允許你在給本地變量賦值時(shí)使用一個(gè)不同的名稱郭毕,而且該語法看上去就像是使用對(duì)象字面量的非簡寫的屬性初始化
// 該語法實(shí)際上與傳統(tǒng)對(duì)象字面量語法相反,傳統(tǒng)語法將名稱放在冒號(hào)左邊函荣、值放在冒號(hào)右邊显押;而在本例中,則是名稱在右邊傻挂,需要進(jìn)行值讀取的位置則被放在了左邊乘碑。
let node = {
type: "Identifier",
name: "foo"
};
let { type: localType, name: localName } = node;
console.log(localType); // "Identifier"
console.log(localName); // "foo"
5. 嵌套對(duì)象解構(gòu)
使用類似于對(duì)象字面量的語法,可以深入到嵌套的對(duì)象結(jié)構(gòu)中去提取想要的數(shù)據(jù)
每當(dāng)有一個(gè)冒號(hào)在解構(gòu)模式中出現(xiàn)金拒,就意味著冒號(hào)之前的標(biāo)識(shí)符代表需要檢查的位置兽肤,而冒號(hào)右側(cè)則是賦值的目標(biāo)。當(dāng)冒號(hào)右側(cè)存在花括號(hào)時(shí),表示目標(biāo)被嵌套在對(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;
語法難點(diǎn):
解構(gòu)賦值時(shí), 需要用 () 括號(hào)包起來, 因?yàn)樵贘S中, {} 表示一個(gè)代碼塊
當(dāng) = 右值為 undefined 和 null時(shí)會(huì)報(bào)錯(cuò), 其他的則正常
使用嵌套的解構(gòu)時(shí)需要小心电禀,因?yàn)槟憧赡軣o意中就創(chuàng)建了一個(gè)沒有任何效果的語句◇孕荩空白花括號(hào)在對(duì)象解構(gòu)中是合法的尖飞,然而它不會(huì)做任何事。
// 沒有變量被聲明宛官! let { loc: {} } = node;
數(shù)組解構(gòu)
1. 語法 -- 變量聲明
數(shù)組解構(gòu)時(shí), 解構(gòu)作用在數(shù)組內(nèi)部的位置上, 而不是作用在對(duì)象的具名屬性上 (所以也就沒有別名的說法, 因?yàn)槎x的就是需要存儲(chǔ)的變量標(biāo)識(shí)符)
-
數(shù)組解構(gòu)時(shí), 是由于他們?cè)跀?shù)組中的位置, 實(shí)際的變量名稱是任意的, 與之對(duì)應(yīng)的對(duì)象解構(gòu), 關(guān)注的是其屬性名
let colors = [ "red", "green", "blue" ]; let [ firstColor, secondColor ] = colors; console.log(firstColor); // "red" console.log(secondColor); // "green"
-
也可以在解構(gòu)模式中忽略一些項(xiàng), 并且只給感興趣的項(xiàng)提供變量名
let colors = [ "red", "green", "blue" ]; let [ , , thirdColor ] = colors; console.log(thirdColor); // "blue"
當(dāng)解構(gòu)賦值表達(dá)式的右側(cè)( = 后面的表達(dá)式)的計(jì)算結(jié)果不是 Iterable(null 或 undefined 或 數(shù)字 或 對(duì)象 等等, 字符串是Iterable) 結(jié)構(gòu)數(shù)據(jù)時(shí), 會(huì)拋出錯(cuò)誤
2. 解構(gòu)賦值 -- 先聲明變量, 在賦值
跟對(duì)象解構(gòu)賦值類似, 不同的是, 數(shù)組解構(gòu)賦值不需要將表達(dá)式包含在圓括號(hào)內(nèi)
let colors = [ "red", "green", "blue" ],
firstColor = "black",
secondColor = "purple";
[ firstColor, secondColor ] = colors;
3. 默認(rèn)值
與對(duì)象一樣, 數(shù)組解構(gòu)賦值同樣允許在數(shù)組任意位置指定默認(rèn)值
let colors = [ "red" ];
let [ firstColor, secondColor = "green" ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
4. 嵌套數(shù)組的解構(gòu)
與解構(gòu)嵌套的對(duì)象相似葫松,可以用類似的方式來解構(gòu)嵌套的數(shù)組。在整個(gè)解構(gòu)模式中插入另一個(gè)數(shù)組模式底洗,解構(gòu)操作就會(huì)下行到嵌套的數(shù)組中
let colors = [ "red", [ "green", "lightgreen" ], "blue" ];
// 隨后
let [ firstColor, [ secondColor ] ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
5. 剩余項(xiàng)
-
類似于函數(shù)的剩余參數(shù)概念, 數(shù)組解構(gòu)有個(gè)類似的腋么、名為剩余項(xiàng)( rest items )的概念,它使用 ... 語法來將剩余的項(xiàng)目賦值給一個(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ù)的剩余參數(shù)一樣, 解構(gòu)的剩余項(xiàng)必須是數(shù)組解構(gòu)模式中最后的部分, 之后不能再有逗號(hào), 否則就是語法錯(cuò)誤
混合解構(gòu)
對(duì)象與數(shù)組解構(gòu)能被用在一起, 以創(chuàng)建更復(fù)雜的解構(gòu)表達(dá)式
-
對(duì)應(yīng)從 JSON 配置結(jié)構(gòu)中抽取數(shù)據(jù)來說, 這種方法尤其有用, 因?yàn)樗恍枰剿髡麄€(gè)結(jié)構(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
參數(shù)解構(gòu)
參數(shù)解構(gòu)的規(guī)則跟對(duì)象解構(gòu), 數(shù)組解構(gòu)一致, 可以使用默認(rèn)參數(shù)亥揖、混合解構(gòu)珊擂, 或使用與屬性不同的變量名
1. 參數(shù)是必須的.
因?yàn)椴荒軐?duì) undefined
進(jìn)行解構(gòu), 所以解構(gòu)參數(shù)是必須的。但若你要求它是可選的费变,可以給解構(gòu)的參數(shù)提供默認(rèn)值來處理這種行為
function setCookie(name, value, { secure, path, domain, expires } = {}) {
// ...
}
2. 參數(shù)解構(gòu)的默認(rèn)值
你可以為參數(shù)解構(gòu)提供可解構(gòu)的默認(rèn)值摧扇,就像在解構(gòu)賦值時(shí)所做的那樣,只需在其中每個(gè)參數(shù)后面添加等號(hào)并指定默認(rèn)值即可挚歧。
function setCookie(name, value,
{
secure = false,
path = "/",
domain = "example.com",
expires = new Date(Date.now() + 360000000)
} = {}
) {
// ...
}