為何使用解構功能
在ES5及早期版本中,開發者們為了從對象和數組中獲取特定數據並賦值給變量,編寫了許多看起來同質化的代碼,如下:
let options = {
repeat:true,
save:false
};
//從對象中取數據
let repeat = options.repeat,
save = options.save;
這段代碼從options對象中提取了repeat和save的值並將其存儲為同名局部變量,提取的過程極為相似,想象一下,如果你要提取更多變量,則必須依次編寫類似的代碼來為變量賦值,如果其中還包含嵌套結構,只靠遍歷是找不到真實信息的,必須要深入挖掘整個數據結構才能找到所需數據。
對象解構
對象解構的語法形式是在一個賦值操作左邊放置一個對象字面量,如:
let node = {
type:"Identifier",
name:"foo"
};
let {type,name} = node;
console.log(type);//"Identifier"
console.log(name);//"foo"
在這段代碼中,node.type的值被存儲在名為type的變量中;node.name的值被存儲在名為name的變量中。
注意:如果使用var、let、const解構聲明變量,必須要提供初始化程序(也就是等號右側的值),否則會導致程序拋出語法錯誤。
解構賦值
同樣可以在給變量賦值時使用解構語法,如下,在定義變量之后想要修改他們的值,可以這樣:
let node = {
type:"Identifier",
name:"foo"
},
type = "Literal",
name = 5;
//使用解構語法為多個變量賦值
({type,name} = node);
console.log(type);//"Identifier"
console.log(name);//"foo"
在這個示例中,聲明變量type和name時初始化了一個值,在后面的幾行中,通過解構賦值的方法,從node對象讀取相應的值重新為這兩個變量賦值。注意:一定要用一對小括號包裹解構賦值語句,javascript引擎將一對開放的花括號視為一個代碼塊,而語法規定,代碼塊不能出現在賦值語句的左側,添加小括號后可以將塊語句轉化為一個表達式,從而實現整個解構賦值的過程。
默認值
使用解構賦值表達式時,如果指定的局部變量名稱在對象中不存在,那么這個局部變量會被賦值為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
為非同名局部變量賦值
到目前為止的每一個實例中,解構賦值使用的都是與對象屬性同名的局部變量,例如,node.type的值被存儲在了變量type中。但如果你希望使用不同命名的局部變量來存儲對象屬性的值,ES6中的一個擴展語法可以滿足:
let node = {
type:"Identifier",
name:"foo"
};
let {type:localType,name:localName} = node;
console.log(localType);//"Identifier"
console.log(localName);//"foo"
當使用其他變量名進行賦值時也可以添加默認值,只需在變量名后添加等號和默認值即可:
let node = {
type:"Identifier"
};
let {type:localType,name:localName = "bar"} = node;
console.log(localType);//"Identifier"
console.log(localName);//"bar"
嵌套對象解構
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
在這個示例中,我們在解構模式中使用了花括號,其含義為在找到node對象中的loc屬性后,應當深入一層繼續查找start屬性。更進一步,也可以使用一個與對象屬性名不同的局部變量名:
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;
console.log(localStart.line);//1
console.log(localStart.column);//1
數組解構
與對象解構的語法相比,數組解構就簡單多了,它使用的是數組字面量,且解構操作全部在數組內完成,而不是像對象字面量語法一樣使用對象的命名屬性:
let colors = ["red","green","blue"];
let [firstColor,secondColor] = colors;
console.log(firstColor);//"red"
console.log(secondColor);//"green"
在這段代碼中,我們從colors數組中解構出了"red"和"green"這兩個值,並分別存儲在變量firstColor和變量secondColor中。在數組解構語法中,我們通過值在數組中的位置進行選取,且可以存儲在任意變量中,未顯式聲明的元素都會直接被忽略。在這個過程中,數組本身不會發生任何變化。
在解構模式中,也可以直接省略元素,只為感興趣的元素提供變量名。比如,如果你只想取數組中的第三個值,則不需要提供第一個和第二個元素的變量名稱:
let colors = ["red","green","blue"];
let [ ,,thirdColor] = colors;
console.log(thirdColor);//"blue"
解構賦值
數組解構也可用於賦值上下文,但不需要用小括號包裹表達式,這一點與對象解構的約定不同。
let colors = ["red","green","blue"],
firstColor = "black",
secondColor = "purple";
[firstColor,secondColor] = color;
console.log(firstColor);//"red"
console.log(secondColor);//"green"
數組解構還有一個獨特的用例:交換兩個變量的值。在ES5中交換兩個變量的值需要引入第三個臨時變量,但在ES6的數組解構中,就不再需要額外的變量了,如下:
let a = 1,
b = 2;
[a,b] = [b,a];
console.log(a);//2
console.log(b);//1
默認值
也可以在數組解構賦值表達式中為數組中的任意位置添加默認值,當指定位置的屬性不存在或其值為undefined時使用默認值:
let colors = ["red"];
let [firstColor,secondColor = "green"] = colors;
console.log(firstColor);//"red"
console.log(secondColor);//"green"
嵌套數組解構
let colors = ["red",["green","lightgreen"],"blue"];
let [firstColor,[secondColor]] = colors;
console.log(firsrColor);//"red"
console.log(secondColor);//"green"
在此示例中,變量secondColor引用的事colors數組中的值"green",該元素包含在數組內部的另一個數組中,所以secondColor兩側的方括號是一個必要的解構模式。同樣,在數組中也可以無限深入去解構,就像在對象中一樣。
不定元素
在數組中,可以通過…語法將數組中的其余元素賦值給一個特定的變量,如下:
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"
注意:在被解構的數組中,不定元素必須為最后一個條目,在后面繼續添加逗號會導致程序拋出語法錯誤。
混合解構
可以混合使用對象解構和數組解構來創建更多復雜的表達式,如此一來,可以從任何混雜着對象和數組的數據解構中提取你想要的信息:
let node = {
type:"Identifier",
name:"foo",
loc:{
start:{
line:1,
column:1
},
end:{
line:1,
column:1
}
},
range:[0,3]
};
let {
loc:{start},
range:[startIndex]
} = node;
console.log(start.line);//1
console.log(start.column);//1
console.log(startIndex);//0
這段代碼分別將node.loc.start和node.range[0]提取到變量start和startIndex中。記住:解構模式中的loc:和range:僅代表他們在對象中所處的位置,也就是該對象的屬性。
原文:https://blog.csdn.net/DFF1993/article/details/82951227