## 一、基礎語法
ES6 允許按照一定模式,從數組和對象中提取值,對變量進行賦值,這被稱為解構(Destructuring)。
~~~javascript
let a = 1;
let b = 2;
let c = 3;
// 數組的解構賦值
let [a, b, c] = [1, 2, 3];
~~~
上面代碼表示,可以從數組中提取值,按照對應位置,對變量賦值。
本質上,這種寫法屬于“模式匹配”,只要等號兩邊的模式相同,左邊的變量就會被賦予對應的值。示例如下:
~~~javascript
let [foo, [[bar], baz]] = [1, [[2], 3]];
let [x, , y] = [1, 2, 3];
~~~
解構不成功,變量的值就等于`undefined`。
~~~javascript
let [foo] = [];
let [bar, foo] = [1];
~~~
以上兩種情況都屬于解構不成功,`foo`的值都會等于`undefined`。
另一種情況是不完全解構,即等號左邊的模式,只匹配一部分的等號右邊的數組。這種情況下,解構依然可以成功。
~~~javascript
let [x, y] = [1, 2, 3];
~~~
如果等號的右邊不是數組,那么將會報錯。
~~~javascript
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
~~~
上面的語句都會報錯,因為等號右邊的值,要么轉為對象以后不具備 Iterator 接口(前五個表達式),要么本身就不具備 Iterator 接口。
## 二、默認值
* 解構賦值允許指定默認值。
~~~javascript
let [foo = true] = []; // foo = true
let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
~~~
> ES6 內部使用嚴格相等運算符(`===`),判斷一個位置是否有值。
> 只有當一個數組成員嚴格等于`undefined`,默認值才會生效。
~~~javascript
let [x = 1] = [undefined]; // x = 1
let [x = 1] = [null]; // x = null
~~~
上面代碼中,如果一個數組成員是`null`,默認值就不會生效,因為`null`不嚴格等于`undefined`。
* 默認值可以引用解構賦值的其他變量,但該變量必須已經聲明。
~~~javascript
let [x = 1, y = x] = []; // x=1; y=1
let [x = 1, y = x] = [2]; // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = []; // ReferenceError: y is not defined
~~~
上面最后一個表達式之所以會報錯,是因為`x`用`y`做默認值時,`y`還沒有聲明。