什么是解構賦值?
解構賦值允許你使用類似數組或對象字面量的語法將數組和對象的屬性賦給各種變量。這種賦值語法極度簡潔,同時還比傳統的屬性訪問方法更為清晰。
通常來說,你很可能這樣訪問數組中的前三個元素:
var first = someArray[0]; var second = someArray[1]; var third = someArray[2];
如果使用解構賦值的特性,將會使等效的代碼變得更加簡潔並且可讀性更高:
var [first, second, third] = someArray;
SpiderMonkey(Firefox的JavaScript引擎)已經支持解構的大部分功能,但是仍不健全。你可以通過bug 694100跟蹤解構和其它ES6特性在SpiderMonkey中的支持情況。
數組與迭代器的解構
以上是數組解構賦值的一個簡單示例,其語法的一般形式為:
[ variable1, variable2, ..., variableN ] = array;
這將為variable1到variableN的變量賦予數組中相應元素項的值。如果你想在賦值的同時聲明變量,可在賦值語句前加入var
、let
或const
關鍵字,例如:
var [ variable1, variable2, ..., variableN ] = array; let [ variable1, variable2, ..., variableN ] = array; const [ variable1, variable2, ..., variableN ] = array;
事實上,用變量
來描述並不恰當,因為你可以對任意深度的嵌套數組進行解構:
var [foo, [[bar], baz]] = [1, [[2], 3]]; console.log(foo); // 1 console.log(bar); // 2 console.log(baz); // 3
此外,你可以在對應位留空來跳過被解構數組中的某些元素:
var [,,third] = ["foo", "bar", "baz"]; console.log(third); // "baz"
而且你還可以通過“不定參數”模式捕獲數組中的所有尾隨元素:
var [head, ...tail] = [1, 2, 3, 4]; console.log(tail); // [2, 3, 4]
當訪問空數組或越界訪問數組時,對其解構與對其索引的行為一致,最終得到的結果都是:undefined
。
console.log([][0]); // undefined var [missing] = []; console.log(missing); // undefined
請注意,數組解構賦值的模式同樣適用於任意迭代器:
function* fibs() { var a = 0; var b = 1; while (true) { yield a; [a, b] = [b, a + b]; } } var [first, second, third, fourth, fifth, sixth] = fibs(); console.log(sixth); // 5
對象的解構
通過解構對象,你可以把它的每個屬性與不同的變量綁定,首先指定被綁定的屬性,然后緊跟一個要解構的變量。
var robotA = { name: "Bender" }; var robotB = { name: "Flexo" }; var { name: nameA } = robotA; var { name: nameB } = robotB; console.log(nameA); // "Bender" console.log(nameB); // "Flexo"
當屬性名與變量名一致時,可以通過一種實用的句法簡寫:
var { foo, bar } = { foo: "lorem", bar: "ipsum" }; console.log(foo); // "lorem" console.log(bar); // "ipsum"
與數組解構一樣,你可以隨意嵌套並進一步組合對象解構:
var complicatedObj = { arrayProp: [ "Zapp", { second: "Brannigan" } ] }; var { arrayProp: [first, { second }] } = complicatedObj; console.log(first); // "Zapp" console.log(second); // "Brannigan"
當你解構一個未定義的屬性時,得到的值為undefined
:
var { missing } = {}; console.log(missing); // undefined
請注意,當你解構對象並賦值給變量時,如果你已經聲明或不打算聲明這些變量(亦即賦值語句前沒有let
、const
或var
關鍵字),你應該注意這樣一個潛在的語法錯誤:
{ blowUp } = { blowUp: 10 }; // Syntax error 語法錯誤
為什么會出錯?這是因為JavaScript語法通知解析引擎將任何以{開始的語句解析為一個塊語句(例如,{console}
是一個合法塊語句)。解決方案是將整個表達式用一對小括號包裹:
({ safe } = {}); // No errors 沒有語法錯誤
解構值不是對象、數組或迭代器
當你嘗試解構null
或undefined
時,你會得到一個類型錯誤:
var {blowUp} = null; // TypeError: null has no properties(null沒有屬性)
然而,你可以解構其它原始類型,例如:布爾值
、數值
、字符串
,但是你將得到undefined
:
var {wtf} = NaN; console.log(wtf); // undefined
你可能對此感到意外,但經過進一步審查你就會發現,原因其實非常簡單。當使用對象賦值模式時,被解構的值需要被強制轉換為對象。大多數類型都可以被轉換為對象,但null
和undefined
卻無法進行轉換。當使用數組賦值模式時,被解構的值一定要包含一個迭代器。
默認值
當你要解構的屬性未定義時你可以提供一個默認值:
var [missing = true] = []; console.log(missing); // true var { message: msg = "Something went wrong" } = {}; console.log(msg); // "Something went wrong" var { x = 3 } = {}; console.log(x); // 3