ES6 容許按照必定模式,從數組和對象中提取值,對變量進行賦值,這被稱爲解構。javascript
let [a, b, c] = [1, 2, 3];
複製代碼
屬於「模式匹配」,只要等號兩邊的模式相同,左邊的變量就會被賦予對應的值。java
解構不成功,變量的值就等於undefined
。數組
左邊的模式,只匹配一部分的等號右邊的數組,解構依然能夠成功。markdown
若是等號的右邊不是數組(或者嚴格地說,不是可遍歷的結構),那麼將會報錯。函數
// 報錯
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
複製代碼
Set 結構,也可使用數組的解構賦值。ui
let [x, y, z] = new Set(['a', 'b', 'c']);
複製代碼
具備 Iterator 接口的數據,均可以採用數組形式的解構賦值。spa
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();
sixth // 5
複製代碼
解構賦值容許指定默認值。code
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
複製代碼
默認值判斷使用嚴格相等運算符(===
),僅嚴格等於undefined
生效,‘’
與null
不生效。orm
默認值能夠引用解構賦值的其餘變量,但該變量必須已經聲明。對象
默認值若是是一個表達式,那麼這個表達式是惰性求值的,即只有在用到的時候,纔會求值。
變量必須與屬性同名,才能取到正確的值。
解構失敗,變量的值等於undefined
。
對象的方法,能夠賦值到某個變量。
// 例一
let { log, sin, cos } = Math;
// 例二
const { log } = console;
log('hello') // hello
複製代碼
變量名與屬性名不一致,必須寫成下面這樣。
let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"
複製代碼
解構也能夠用於嵌套結構的對象。
let obj = {
p: [
'Hello',
{ y: 'World' }
]
};
let { p: [x, { y }] } = obj;
x // "Hello"
y // "World"
// p是模式,不是變量,所以不會被賦值。要賦值的寫成:let { p, p: [x, { y }] } = obj;
複製代碼
解構模式是嵌套的對象,並且子對象所在的父屬性不存在,那麼將會報錯。
// 報錯
let {foo: {bar}} = {baz: 'baz'};
複製代碼
對象的解構賦值能夠取到繼承的屬性。
屬性名能夠是表達式。
let arr = [1, 2, 3];
let {0 : first, [arr.length - 1] : last} = arr;
first // 1
last // 3
複製代碼
將一個已經聲明的變量用於解構賦值,必須很是當心。
// 錯誤的寫法
let x;
{x} = {x: 1};
// SyntaxError: syntax error
// 正確的寫法
let x;
({x} = {x: 1});
複製代碼
字符串也能夠解構賦值。這是由於此時,字符串被轉換成了一個相似數組的對象。
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
複製代碼
解構賦值的規則是,只要等號右邊的值不是對象或數組,就先將其轉爲對象。因爲undefined
和null
沒法轉爲對象,因此對它們進行解構賦值,都會報錯。
可是數值和布爾值能夠先轉爲對象,所以不會報錯。
undefined
就會觸發函數參數的默認值。[[1, 2], [3, 4]].map(([a, b]) => a + b);
// [ 3, 7 ]
function move({x, y} = { x: 0, y: 0 }) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]
[1, undefined, 3].map((x = 'yes') => x);
// [ 1, 'yes', 3 ]
複製代碼
賦值語句的非模式部分,可使用圓括號。
let b; // 先聲明
[(b)] = [3]; // 正確
({ p: (d) } = {}); // 正確
複製代碼