背景:解構(gòu)(destructuring)有何用杯矩?
let heros = {
no1: "呂布",
no2: "張飛",
weapons: [ "刀","劍","弓箭"]
};
// 從對(duì)象中提取數(shù)據(jù)
let lb = heros.no1, zs = heros.no2, weapons = heros.weapons;
想象一下,若heros中有100萬(wàn)個(gè)變量需要提取處理呢沽损?若 是多層嵌套的數(shù)據(jù)結(jié)構(gòu)呢?可能會(huì)為了一點(diǎn)數(shù)據(jù)而挖掘整個(gè)結(jié)構(gòu)猛计,做大量低效重復(fù)的工作唠摹。
解構(gòu)賦值
解構(gòu)賦值--使得把數(shù)據(jù)結(jié)構(gòu)分解為更小的部分時(shí),提取數(shù)據(jù)會(huì)變得更容易有滑,更高效跃闹。
解構(gòu)賦值語(yǔ)法是一種 Javascript 表達(dá)式。解構(gòu)使用的語(yǔ)法--就是對(duì)象與數(shù)組的字面量語(yǔ)法毛好。--按照一定模式望艺,從數(shù)組和對(duì)象中提取值,對(duì)變量進(jìn)行賦值肌访,這被稱為解構(gòu)(Destructuring)找默。
基本原則如下:
數(shù)組的元素是按次序排列的,變量的取值由它的位置決定吼驶;
對(duì)象的屬性沒(méi)有次序惩激,變量必須與屬性同名,才能取到正確的值蟹演。
數(shù)組的解構(gòu)賦值
1 變量聲明并賦值時(shí)的解構(gòu) 或者先聲明變量再賦值
let foo = ["one", "two", "three"];
let [m, n, three] = foo;
console.log(m); // "one"
console.log(n); // "two"
console.log(three); // "three"
//-或者
let [foo, [[bar], baz]] = [1, [[2], 3]];
console.log(foo); // 1
console.log(bar); // 2
console.log(baz); // 3
//先聲明再賦值
let a, b;
[a, b] = [1, 2];
注意1:在使用 var 风钻、 let 、 const 進(jìn)行數(shù)組解構(gòu)時(shí)酒请,必須提供初始化 器(即等號(hào) 右邊的值)
const [a ,b];
let [d,e];
// Uncaught SyntaxError: Missing initializer in destructuring declaration
注意2:如果解構(gòu)不成功骡技,變量的值就等于undefined。
let [foo] = [];
let [bar, foo] = [1];
//以上兩種情況都屬于解構(gòu)不成功羞反,foo的值都會(huì)等于undefined布朦。
注意3:不完全解構(gòu)-等號(hào)左邊的模式,只匹配一部分的等號(hào)右邊的數(shù)組昼窗。這種情況下是趴,解構(gòu)依然可以成功。
let [x, y] = [1, 2, 3];// x//1 y //2
let [a, [b], d] = [1, [2, 3], 4];// a //1 b // 2 d // 4
注意4:解構(gòu)報(bào)錯(cuò)--如果等號(hào)的右邊不是數(shù)組(或者嚴(yán)格地說(shuō)澄惊,不是可遍歷的結(jié)構(gòu)唆途,不具備 Iterator 接口),那么將會(huì)報(bào)錯(cuò)掸驱。
// 報(bào)錯(cuò)
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
2 忽略某些值窘哈,只對(duì)感興趣值解構(gòu)
let [ , , third] = ["foo", "bar", "baz"]; //逗號(hào)-, 為數(shù)組前面的項(xiàng)提供的占位符
console.log(third); // "baz"
3 默認(rèn)值
ES6 解構(gòu)內(nèi)部使用嚴(yán)格相等運(yùn)算符(===),判斷一個(gè)位置是否有值亭敢。所以,只有當(dāng)一個(gè)數(shù)組成員嚴(yán)格等于undefined图筹,默認(rèn)值才會(huì)生效帅刀。
const [a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7 --默認(rèn)值生效
let [x = 1] = [undefined];
x // 1 --默認(rèn)值生效
let [x = 1] = [null];
x // null
注意1:如果默認(rèn)值是一個(gè)表達(dá)式让腹,那么這個(gè)表達(dá)式是惰性求值的,即只有在用到的時(shí)候扣溺,才會(huì)求值骇窍。
function f() {
console.log('aaa');
}
let [x = f()] = [1]; //因?yàn)閤能取到值,所以函數(shù)f根本不會(huì)執(zhí)行锥余。
//上面的代碼其實(shí)等價(jià)于下面的代碼腹纳。
let x;
if ([1][0] === undefined) {
x = f();
} else {
x = [1][0];
}
注意2:默認(rèn)值可以引用解構(gòu)賦值的其他變量,但該變量必須已經(jīng)聲明驱犹。
let [x = 1, y = x] = [2]; // x=2; y=2
let [x = y, y = 1] = []; // ReferenceError: y is not defined
//--因?yàn)閤用y做默認(rèn)值時(shí)嘲恍,y還沒(méi)有聲明
4 剩余項(xiàng) (...) -- 將剩余數(shù)組賦值給一個(gè)變量(數(shù)組)
當(dāng)解構(gòu)一個(gè)數(shù)組時(shí),可以使用剩余模式雄驹,將數(shù)組剩余部分賦值給一個(gè)變量佃牛。
var [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3] --注意,這是個(gè)數(shù)組
注意:如果剩余元素右側(cè)有逗號(hào)医舆,會(huì)拋出 SyntaxError
俘侠,因?yàn)槭S嘣乇仨毷菙?shù)組的最后一個(gè)元素,之后不能再有逗號(hào)蔬将,否則就是語(yǔ)法錯(cuò)誤爷速。
var [a, ...b,] = [1, 2, 3];
// SyntaxError: rest element may not have a trailing comma
應(yīng)用1::若要取出特定項(xiàng) 并要求保留剩余的值,則剩余項(xiàng)是非常有用的霞怀。
應(yīng)用2:方便地克隆數(shù)組在JS中是個(gè)明顯被遺漏的功能惫东。
在ES5中常用的concat()方法來(lái)克隆數(shù)組 (方便簡(jiǎn)單);在ES6中里烦,使用剩余項(xiàng)的語(yǔ)法克隆數(shù)組(小技巧)
// 在 ES5 中克隆數(shù)組
let colors = [ "red", "green", "blue" ];
let clonedColors = colors.concat();
colors[2] = "skyblue";
console.log(clonedColors); //"[red,green,blue]"
concat()方法本意是合并兩個(gè)數(shù)組凿蒜,但不使用任何參數(shù)來(lái)調(diào)用此方法,會(huì)獲得原 數(shù)組的一個(gè)克隆品胁黑。
// 在ES6中废封,使用剩余項(xiàng)的語(yǔ)法克隆數(shù)組 ,達(dá)到上述同樣效果
let colors = [ "red", "green", "blue" ];
let [ ...clonedColors ] = colors;
colors[2] = "skyblue";
console.log(clonedColors); //"[red,green,blue]"
5 嵌套的數(shù)組 解構(gòu)
在整個(gè)解構(gòu)模式中插入另一 個(gè)數(shù)組模式丧蘸,解構(gòu)操作會(huì)下行到 嵌套的數(shù)組中漂洋。可以使用任意深 度的數(shù)組嵌套解構(gòu)力喷。
let colors = [ "red",[ "green", "lightgreen" ], "blue" ];
let [ firstColor, [ secondColor ] ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
應(yīng)用篇
交換變量 - 在一個(gè)解構(gòu)表達(dá)式中可以輕松交換兩個(gè)變量的值刽漂。
//在 ES5 中互換值需要使用第三個(gè)變量作為臨時(shí)變量:
let a = 1, b = 2, tmp;
tmp =a ; a = b; b = tmp;
console.log(a); // 2
console.log(b); // 1
// 在 ES6 中互換值
let a = 1, b = 2;
[ a, b ] = [ b, a ];
console.log(a); // 2
console.log(b); //1
解析一個(gè)從函數(shù)返回的數(shù)組
從一個(gè)函數(shù)返回一個(gè)數(shù)組是十分常見(jiàn)的情況。解構(gòu)使得處理返回值為數(shù)組時(shí)更加方便弟孟。
function f() {
return [1, 2];
}
let a, b;
[a, b] = f();
console.log(a); // 1
console.log(b); // 2
總結(jié)
本質(zhì)上贝咙,解構(gòu)賦值這種寫(xiě)法屬于“模式匹配”,只要等號(hào)兩邊的模式相同拂募,左邊的變量就會(huì)被賦予對(duì)應(yīng)的值庭猩。
數(shù)組的元素是按次序排列的窟她,變量的取值由它的位置決定;