在ES5中萤厅,從對象和數(shù)組中獲取特定數(shù)據(jù)并賦值給變量阎毅,有許多看起來同質(zhì)化的代碼
let options = {
repeat: true,
save: false
};
// 從對象中提取數(shù)據(jù)
let repeat = options.repeat,
save = options.save;
對象解構
let node = {
type: "Identifier",
name: "foo"
};
let { type, name } = node;
console.log(type); // "Identifier"
console.log(name); // "foo"
如果不是用在聲明中,用在賦值中需要加小括號,因為語法規(guī)定嗤练,代碼塊語句不允許出現(xiàn)在賦值語句左側(cè)榛了。
let node = {
type: "Identifier",
name: "foo"
},
type = "Literal",
name = 5;
// 使用解構來分配不同的值
({ type, name } = node);
console.log(type); // "Identifier"
console.log(name); // "foo"
添加小括號后可以將塊語句轉(zhuǎn)化為一個表達式,從而實現(xiàn)整個解構賦值過程煞抬。
解構賦值表達式的值與表達式右側(cè)(也就是=右側(cè))的值相等
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ù)時傳入了一個解構表達式霜大,由于JS表達式的值為右側(cè)的值,因而此處傳入的參數(shù)等同于node革答,且變量type和name被重新賦值战坤,最終將node傳入outputlnfo()函數(shù)
默認值
使用解構賦值表達式時,如果指定的局部變量名稱在對象中不存在残拐,那么這個局部變量會被賦值為undefined
let node = {
type: "Identifier",
name: "foo"
};
let { type, name, value } = node;
console.log(type); // "Identifier"
console.log(name); // "foo"
console.log(value); // undefined
當指定的屬性不存在時途茫,可以隨意定義一個默認值,在屬性名稱后添加一個等號(=)和相應的默認值即可
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設置了默認值true囊卜,只有當node上沒有該屬性或者該屬性值為undefined時該值才生效。此處沒有node.value屬性错沃,因為value使用了預設的默認值
為非同名局部變量賦值
let node = {
type: "Identifier",
name: "foo"
};
let { type: localType, name: localName } = node;
console.log(localType); // "Identifier"
console.log(localName); // "foo"
這段代碼使用了解構賦值來聲明變量localType和localName栅组,這兩個變量分別包含node.type和node.name屬性的值。
嵌套對象解構
解構嵌套對象仍然與對象字面量的語法相似枢析,可以將對象拆解以獲取想要的信息
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
數(shù)組解構
let colors = [ "red", "green", "blue" ];
let [ firstColor, secondColor ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
也可以直接省略元素玉掸,只為感興趣的元素提供變量名
let colors = [ "red", "green", "blue" ];
let [ , , thirdColor ] = colors;
console.log(thirdColor); // "blue"
用于直接賦值時,不需要加小括號
let colors = [ "red", "green", "blue" ],
firstColor = "black",
secondColor = "purple";
[ firstColor, secondColor ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
變量交換
可以用數(shù)組解構的方法很方便的實現(xiàn)變量交換
// 在 ES6 中互換值
let a = 1,
b = 2;
[ a, b ] = [ b, a ];
console.log(a); // 2
console.log(b); // 1
默認值
也可以在數(shù)組解構賦值表達式中為數(shù)組中的任意位置添加默認值醒叁,當指定位置的屬性不存在或其值為undefined時使用默認值
let colors = [ "red" ];
let [ firstColor, secondColor = "green" ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
嵌套數(shù)組解構
let colors = [ "red", [ "green", "lightgreen" ], "blue" ];
// 隨后
let [ firstColor, [ secondColor ] ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
不定元素
在數(shù)組中司浪,可以通過...語法將數(shù)組中的其余元素賦值給一個特定的變量
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ù)組賦值
在ES5中,開發(fā)者們經(jīng)常使用concat()方法來克隆數(shù)組
// 在 ES5 中克隆數(shù)組
var colors = [ "red", "green", "blue" ];
var clonedColors = colors.concat();
console.log(clonedColors); //"[red,green,blue]"
在ES6中辐益,可以通過不定元素的語法來實現(xiàn)相同的目標
let colors = [ "red", "green", "blue" ];
let [ ...clonedColors ] = colors;
console.log(clonedColors); //"[red,green,blue]"
混合解構
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ù)
普通寫法
// options 上的屬性表示附加參數(shù)
function setCookie(name, value, options) {
options = options || {};
let secure = options.secure,
path = options.path,
domain = options.domain,
expires = options.expires;
// 設置 cookie 的代碼
}
// 第三個參數(shù)映射到 options
setCookie("type", "js", {
secure: true,
expires: 60000
});
使用解構參數(shù)
function setCookie(name, value, { secure, path, domain, expires }) {
// 設置 cookie 的代碼
}
setCookie("type", "js", {
secure: true,
expires: 60000
});
解構參數(shù)需要使用對象或數(shù)組解構模式代替命名參數(shù)断傲。如果調(diào)用函數(shù)時不提供被解構的參數(shù)會導致程序拋出錯誤。
// 出錯智政!
setCookie("type", "js");
因為當調(diào)用setCookie()函數(shù)時认罩,JS引擎實際上做了以下這些事情
function setCookie(name, value, options) {
let { secure, path, domain, expires } = options;
// 設置 cookie 的代碼
}
如果解構賦值表達式的右值為null或undefined,則程序會報錯续捂。
如果解構參數(shù)是必需的垦垂,大可忽略掉這些問題;但如果希望將解構參數(shù)定義為可選的牙瓢,那么就必須為其提供默認值來解決這個問題
function setCookie(name, value, { secure, path, domain, expires } = {}) {
// ...
}
這個示例中為解構參數(shù)添加了一個新對象作為默認值劫拗,secure、path矾克、domain及expires這些變量的值全部為undefined页慷,這樣即使在調(diào)用setCookie()時未傳遞第3個參數(shù),程序也不會報錯
默認值
function setCookie(name, value,
{
secure = false,
path = "/",
domain = "example.com",
expires = new Date(Date.now() + 360000000)
} = {}
) {
// ...
}
將默認值放到setCookieDefaults對象中,在解構參數(shù)中可以直接使用這個對象來為每一個綁定設置默認參數(shù)酒繁。如果要改變默認值滓彰,可以立即在setCookieDefaults中修改,改變的數(shù)據(jù)將自動同步到所有出現(xiàn)過的地方州袒。
其他解構
字符串解構
字符串也可以解構賦值揭绑。這是因為,字符串被轉(zhuǎn)換成了一個類似數(shù)組的對象
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"
類似數(shù)組的對象都有一個length屬性郎哭,因此還可以對這個屬性解構賦值
const {length} = 'hello';
console.log(length);//5
數(shù)值和布爾值解構
解構賦值時他匪,如果等號右邊是數(shù)值和布爾值,則會先轉(zhuǎn)為對象
let {toString:s1} = 123;
console.log(s1 === Number.prototype.toString);//true
let {toString:s2} = true;
console.log(s2 === Boolean.prototype.toString);//true
解構賦值的規(guī)則是夸研,只要等號右邊的值不是對象或數(shù)組邦蜜,就先將其轉(zhuǎn)為對象。由于undefined和null無法轉(zhuǎn)為對象陈惰,所以對它們進行解構賦值畦徘,都會報錯
let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError