基本語(yǔ)法
let a = 1;
let b = 2;
let c = 3;
可以寫成:
let [a, b, c] = [1, 2, 3];
只要等號(hào)兩邊的模式相同,左邊變量就會(huì)被賦予對(duì)應(yīng)的值。
let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3
let [ , , third] = ['foo', 'bar', 'baz'];
third // 'baz'
let [x, , y] = [1, 2, 3]
x // 1
y // 3
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
let [x, y, ...z] = ['a'];
x // 'a'
y // undefined
z // []
如果解構(gòu)不成功,變量的值就等于 undefined
let [foo] = [];
let [bar, foo] = [1];
以上兩種情況都屬于解構(gòu)不成功,foo
的值就等于 undefined
對(duì)于Set解構(gòu),也可是使用數(shù)組的解構(gòu)賦值
let [x, y, z] = new Set(['a', 'b', 'c']);
x // 'a'
事實(shí)上,只要某種數(shù)據(jù)結(jié)構(gòu)具有 Iterator 接口,都可以采用數(shù)組形式的結(jié)構(gòu)賦值。
默認(rèn)值
let [foo = true] = [];
foo // true
let [x, y = 'b'] = ['a']; // x = 'a', y = 'b'
let [x, y = 'b'] = ['a', undefined]; // x = 'a', y = 'b'
let [x = 1] = [null];
x // null
ES6 內(nèi)部使用嚴(yán)格相等運(yùn)算符(===
),判斷是否有值。如果一個(gè)數(shù)組成員不嚴(yán)格等于 undefined
,默認(rèn)值是不會(huì)生效的。
如果默認(rèn)值是一個(gè)表達(dá)式,那么這個(gè)表達(dá)式是惰性求值的,即只有在用到的時(shí)候,才會(huì)求值
function f() {
console.log('aaa');
}
let [x = f()] = [1];
上面代碼中,因?yàn)?x
能取到值,所以函數(shù) f
根本不會(huì)去執(zhí)行。
默認(rèn)值可以引用結(jié)構(gòu)賦值的其它變量,但該變量 必須已經(jīng)聲明。
let [x = y, y = 1] = []; //ReferenceError
對(duì)象的結(jié)構(gòu)賦值
let { foo, bar } = { foo: 'aaa', bar: 'bbb' }
foo // 'aaa'
bar // 'bbb'
如果變量名與屬性名不一致,必須寫成下面這樣,
var { foo: baz } = { foo: 'aaa', bar: 'bbb' }
baz // 'aaa'
let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'
解構(gòu)也可以用于嵌套解構(gòu)的對(duì)象
let obj = {
p: [
'hello',
{ y: 'world' }
]
}
let { p: [x, { y }] } = obj;
x // 'hello'
y // 'world'
注意,這時(shí) p
是模式,不是變量,因此不會(huì)被賦值。如果 p
也要作為變量賦值,可以寫成
let {p, p: [x, { y }]} = obj;
x // 'hello'
y // 'world'
p // ['hello', {y: 'world'}]
字符串的結(jié)構(gòu)賦值
const [a, b, c, d, e] = 'hello';
a // 'h'
b // 'e'
c // 'l'
d // 'l'
e // 'o'
類似數(shù)組的對(duì)象都有一個(gè) length
屬性,因此還可以對(duì)這個(gè)屬性結(jié)構(gòu)賦值。
let {length: len} = 'hello';
len // 5
數(shù)值和布爾值的結(jié)構(gòu)賦值
如果等號(hào)右邊是數(shù)值和布爾值,則會(huì)先轉(zhuǎn)為對(duì)象。
let { toString: s } = 123;
s === Number.prototype.toString // true
數(shù)值的包裝對(duì)象有toString屬性,因此變量 s
能取到值。
結(jié)構(gòu)賦值的規(guī)則是,只要等號(hào)右邊的值不是對(duì)象或數(shù)組,就先將其轉(zhuǎn)為對(duì)象。由于 undefined
和 null
無(wú)法轉(zhuǎn)為對(duì)象,所以對(duì)它們進(jìn)行結(jié)構(gòu)賦值,都會(huì)報(bào)錯(cuò)。
let { prop: x } = undefined; // TypeError
let { prop: y} = null; // TypeError
函數(shù)參數(shù)的解構(gòu)賦值
function add([x, y]) {
return x + y;
}
add([1, 2]); // 3
[[1, 2], [3, 4]].map(([a, b]) => a + b);
// [3, 7]
圓括號(hào)問(wèn)題
對(duì)于編譯器來(lái)說(shuō),一個(gè)式子到底是模式,還是表達(dá)式,沒(méi)有辦法從一開(kāi)始就知道,必須解析到(或即系不到)等號(hào)才能知道。
所以最好不要在模式中放置圓括號(hào)。
不能使用圓括號(hào)的情況
- 變量聲明語(yǔ)句
let [(a)] = [1];
- 函數(shù)參數(shù)
function f([(z)]) { return z; }
- 賦值語(yǔ)句的模式
({p: a}) = { p: 42 }
以上代碼全部報(bào)錯(cuò)。
可以使用圓括號(hào)的情況
[(b)] = [3]; // 正確
({ p: (d) } = {}); //正確
[(parseInt.prop)] = [3]; //正確
用途
- 交換變量的值
let x = 1;
let y = 2;
[x, y] = [y, x];
- 從函數(shù)返回多個(gè)值
function example() {
return [1, 2, 3];
}
let [a, b, c] = example();
- 函數(shù)參數(shù)的定義
- 提取JSON的數(shù)據(jù)
- 函數(shù)參數(shù)的默認(rèn)值
function example({name = 'abc', age = 12}) {
}
- 遍歷Map解構(gòu)
- 輸入模塊的指定方法
const { View, Span } = require("react-native");