解構賦值
定義:ES6中允許按照一定模式從數組和對象中提取值,然後對變量進行賦值。
1.數組的解構賦值
let [a,b,c] = [1,2,3] //a=1,b=2,c=3
let [ foo,[[bar],baz]]=[1,[[2],3]] // foo =1,bar=2,baz=3
本質上這種寫法屬於模式匹配,只要等號兩邊的模式相同,左邊的變量就會被賦予對應的值。
如果結構不成功,變量的值就等於Undefined
let [foo] =[]; //foo undefined
let [bar,foo]=[1] //foo undefined
不完全解構:即等號左邊的模式只匹配到右邊模式的的一部分變量,但結構是可以成功的。
let [x,y]=[1,2,3] //x=1,y=2
let [a,[b],d]=[1,[2,3],4]; a=1,b=2,d=4
如果等號右邊的值或是轉爲對象之後不具備Iterator接口,或不具備Iterator接口那麼解構就會報錯
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null
let [foo] ={} //這些解構都會報錯
解構賦值允許設置默認值
let [foo=true]=[]; // foo =true
let [x,y='b']=['a']; //x='a' y='b'
2.對象的結構賦值
數組的解構是按次序進行的,變量的取值是由它的位置決定。而對象是沒有次序的,變量必須與屬性同名才能取得正確的值。
如果變量沒有對應的同名屬性,則等於undefined。
let {bar,foo} ={foo:"aaa",bar:"bbb"}; //foo="aaa" bar="bbb"
如果變量名與屬性名不一致,則必須要寫成下面這樣:
let {foo:baz}={foo:'aaa',bar:'bbb'}; //baz="aaa";
實際上說明,對象的解構賦值是下面形式的簡寫
let {foo:foo,bar:bar}={foo:'aa',bar:'bb'}; //foo='aa' bar='bb'
**對象的解構賦值的內部機制:**是先找到同名屬性,然後再賦值給對應的變量,真正被賦值的其實是後者,而不是前者
let {foo:baz,bar:bar}={foo:'aa',bar:'bb'};
// baz ='aa'
//foo error:foo is not defined
這說明foo只是匹配模式,不會賦值。真正被賦值的變量是baz
3.字符串的結構賦值
字符串也可以解構賦值,因爲字符串被轉換成一個類似數組的對象
const [a,b,c]='his';
// a='h' b=i c=s
類似數組的對象都有一個length屬性,可以對其進行解構賦值
let {length:len}='hello'; //len=5
4.數值和布爾值的解構賦值
解構賦值時如果等號右邊是數值和布爾值,則會先轉爲對象。
let {toString :s} =123;
s === Number.prototype.toString //true
let {toString :s}=true;
s === Boolean.protype.toString //true
數值和布爾值的包裝對象都有toString屬性,因此變量S都能取到值。
由於undefined和null無法轉爲對象,所以對他們進行解構賦值都會報錯
let {prop:x} = undefined; //TypeError
let {prop:y} = null; //TypeError