變量的解構(gòu)賦值
從數(shù)組和對(duì)象中提取值靠汁,對(duì)變量進(jìn)行賦值蜂大,這被稱為解構(gòu)。
let [a,b,c] = [1,2,3];
可以從數(shù)組中提取值蝶怔,按照對(duì)應(yīng)位置奶浦,對(duì)變量賦值。
這種寫法屬于 “模式匹配”踢星,只要等號(hào)兩邊的模式相同澳叉,左邊的變量就會(huì)被 賦予 對(duì)應(yīng)的值。
下面是 一些 使用 嵌套數(shù)組進(jìn)行解構(gòu)的例子斩狱。
let [foo,[bar],baz] = [1,[2],3];
// foo 1, bar 2,baz 3;
let [ , ,third] = ['foo','bar','baz'];
// third baz;
let [x, ,y] = [1,2,3];
// x 1
// y 3
let [head,...tail] = [1,2,3,4];
// head 1
// tail [2,3,4];
let [x,y,...z] = ['a'];
// x "a"
// y undefined
// z []
如果 解構(gòu)不成功耳高,變量值 等于 undefined。
···
let [foo] = [];
let [bar,foo] = [1];
···
上面 代碼 所踊,都屬于 解構(gòu) 不成功泌枪,foo 的 值 都會(huì) 等于 undefined。
另一種 情況 是 不完全解構(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
上面 兩個(gè)例子,屬于 不完全解構(gòu)遏考,但是可以成功慈鸠。
如果等號(hào)右邊 不是數(shù)組,那么將會(huì)報(bào)錯(cuò)灌具。
(嚴(yán)格地說 青团, 不可遍歷的結(jié)構(gòu))
所以,等號(hào)兩邊的模式相同咖楣,才可以對(duì)其 賦值督笆。
布爾值
返回的是 true 和 false。
解構(gòu)賦值 的 規(guī)則是 诱贿, 只要等號(hào)右邊的值娃肿,不是對(duì)象或數(shù)組,就先將其轉(zhuǎn)為對(duì)象珠十。
由于料扰,undefined 和 null 無法 轉(zhuǎn)為 對(duì)象,所以焙蹭,對(duì)他們進(jìn)行解構(gòu)賦值晒杈,都會(huì)報(bào)錯(cuò)。
let {prop : x} = undefined; // TypeError;
let {prop : y} = null; // TypeError;
函數(shù)參數(shù)的解構(gòu)賦值壳嚎。
函數(shù)的參數(shù)桐智,也可以使用,解構(gòu)賦值烟馅。
function add([x,y]){
return x + y
}
add([1,2]); // 3
函數(shù)add的參數(shù)表面上是一個(gè)數(shù)組说庭,但在傳入?yún)?shù)的那一刻,數(shù)組參數(shù)就被解構(gòu)成變量x和y郑趁。對(duì)于函數(shù)內(nèi)部的代碼來說刊驴,它們能感受到的參數(shù)就是 x 和 y 。
[ [1,2],[3,4] ].map( ([a,b]) => a+b );
// [3,7];
首先寡润,這是個(gè)捆憎,箭頭函數(shù), 傳參傳的是數(shù)組梭纹,a躲惰,b 。
箭頭函數(shù)变抽,如果础拨,不寫 {} 大括號(hào),直接返回绍载,
如果不需要直接返回的話诡宗,寫上{},
然后击儡,用 map 這個(gè) 方法塔沃,循環(huán),解構(gòu)數(shù)組阳谍,
先算蛀柴,二維數(shù)組的 求(1,2) 返回 3 ,
再算边坤,(3,4) 名扛,返回 7 。
函數(shù)的解構(gòu)賦值茧痒,可以肮韧,使用默認(rèn)值。
function move( {x = 0,y = 0} = {} ){
return [x,y];
}
move({x : 3,y : 8}); // [3,8]
move({x : 3}); // [3,0]
move({}); // [0,0]
move(); // [0,0]
上面的代碼中旺订,函數(shù) move 的 參數(shù) 是一個(gè) 對(duì)象弄企,通過對(duì)這個(gè)對(duì)象進(jìn)行解構(gòu),得到變量x 和 y
的 值区拳。如果 解析 失敗拘领, x 和 y 等于 默認(rèn)值。
function move({x,y} = { x:0,y:0 } ){
return [x,y]
}
move({x : 3,y : 8}) // [3,8]
move({x : 3}); // [3,undefined]
move({}); // [undefined,undefined]
move(); // [0,0];
上面代碼是為 函數(shù) move 的 參數(shù) 指定默認(rèn)值樱调, 而不是為變量x 和 y 指定默認(rèn)值约素,所以會(huì)得到與前一種届良,寫法不同的結(jié)果。
= 左邊是變量圣猎,右邊是 參數(shù)士葫;
undefined 就會(huì),觸發(fā)函數(shù)參數(shù)送悔,的默認(rèn)值慢显。
[1,undefined,3].map((x = 'yes') => x);
// [1,'yes',3]
圓括號(hào)問題
解構(gòu)賦值雖然很方便,但是解析起來并不容易欠啤。對(duì)于編譯器來說荚藻,一個(gè)式子到底是模式,還是表達(dá)式洁段,沒有辦法從一開始就知道应狱,必須解析到(或解析不到)等號(hào)才能知道。
由此帶來的問題是祠丝,如果模式中出現(xiàn)圓括號(hào)怎么處理侦香。ES6 的規(guī)則是,只要有可能導(dǎo)致解構(gòu)的歧義纽疟,就不得使用圓括號(hào)罐韩。
但是,這條規(guī)則實(shí)際上不那么容易辨別污朽,處理起來相當(dāng)麻煩散吵。因此,建議只要有可能蟆肆,就不要在模式中放置圓括號(hào)矾睦。
不能 使用 圓括號(hào) 的 情況。
- 變量 聲明 語句炎功。
// 全部報(bào)錯(cuò)
let [(a)] = [1];
let {x: (c)} = {};
let ({x: c}) = {};
let {(x: c)} = {};
let {(x): c} = {};
let { o: ({ p: p }) } = { o: { p: 2 } };
上面 6 個(gè)語句都會(huì)報(bào)錯(cuò)枚冗,因?yàn)樗鼈兌际亲兞柯暶髡Z句,模式不能使用圓括號(hào)蛇损。
- 函數(shù) 參數(shù)赁温。
// 報(bào)錯(cuò)
function f([(z)]) { return z; }
// 報(bào)錯(cuò)
function f([z,(x)]) { return x; }
- 賦值語句的模式。
// 全部報(bào)錯(cuò)
({ p: a }) = { p: 42 };
([a]) = [5];
// 報(bào)錯(cuò)
[({ p: a }), { x: c }] = [{}, {}];