```javascript
let [foo, [[bar], baz]] = [1, [[2], 3]]
foo // 1
bar // 2
baz // 3
let [ ,, third] = ['foo', 'bar', 'baz']
third // 'baz'
let [head, ...tail] = [1, 2, 3, 4]
head // 1
tail // [2, 3, 4]
let [x, y, ...z] = ['a']
x // 'a'
y // undefined
z // []
let [x, y, z] = new Set(['a', 'b', 'c'])
x // 'a'
// 以下語句報錯
let [foo] = 1
let [foo] = false
let [foo] = NaN
let [fool] = undefined
let [foo] = null
let [foo] = {}
```
>上面報錯的語句,是因為等號右邊的值,要么轉為對象以后不具備Iterator接口(前五個表達式),要么本身不具備Iterator接口(最后一個表達式)。
事實上,只要某種數據結構具有Iterator接口,都可以采用數組形式的解構賦值。
```
function* fibs () {
let a = 0
let b = 1
while (true) {
yield a
[a, b] = [b, a + b]
}
}
let [first, second, third, fourth, fifth, sixth] = fibs()
first // 0
second // 1
third // 1
fourth // 2
fifth // 3
sixth // 5
```
>上面代碼中,`fibs`是一個Generator函數,原生具有Iterator接口,解構賦值會依次從這個接口獲取值。
*****
# 解構賦值允許指定默認值
* ES6內部使用嚴格相等運算符(`===`)來判斷一個位置是否有值。所以,只有當一個數組成員嚴格等于`undefined`,默認值才會生效。
```
let [x = 1] = [undefined]
x // 1
let [x = 1] = [null]
x // null
```
* 如果默認值是一個表達式,那么這個表達式是惰性求值的,即只有在用到的時候才會求值。
```
function f () {
return 'aaa'
}
let [x = f()] = [1]
```
> 上面代碼中,因為`x`不使用默認值,所以函數`f`根本不會執行。
* 默認值可以引用解構賦值的其他變量,但該變量必須已經聲明。
```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
```