
概念:
ES6允許按照一定模式從數(shù)組和對象中提取值,然后對變量進(jìn)行賦值,這被稱為解構(gòu)(Destructuring)。
1、數(shù)組
按照數(shù)組對應(yīng)位置將數(shù)組右邊的值賦給左邊的變量或常量,如果沒找到將賦值undefined。
//1、完全解構(gòu)
let [a, b, c] = [1, 2, 3];
a // 1
b // 2
c // 3
// 2、部分解構(gòu)
let [a, ,c] = [1, 2, 3];
a // 1
c // 3
//3、超出解構(gòu)
let [a, b, c] = [1];
a //
b、c // undefined
//4、擴展運算符解構(gòu)
let [a, ...b] = [1, 2, 3];
a // 1
b // [2, 3]
//5、嵌套解構(gòu)
let [a, [[b], c]] = [1, [[2], 3]];
a // 1
b // 2
c // 3
// 其實嵌套解構(gòu)同樣也是根據(jù)數(shù)組數(shù)據(jù)的結(jié)構(gòu)來取值的,無論嵌套基層,
// 同時也符合上面的解構(gòu)規(guī)則。
// 6、默認(rèn)值
let [a = 1, b = 2, b = 3] = [4, undefined, null];
a // 4
b // 2
c // null
// ES6 內(nèi)部使用嚴(yán)格相等運算符(===),判斷一個位置是否有值。
// 所以,只有當(dāng)一個數(shù)組成員嚴(yán)格等于undefined,默認(rèn)值才會生效。
2、對象
對象的解構(gòu)與數(shù)組有一個重要的不同。數(shù)組的元素是按次序排列的,變量的取值由它的位置決定;而對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值。
//1、完全解構(gòu)
let {a, b, c} = {a: 1. b: 2, c: 3};
a // 1
b // 2
c // 3
//2、選擇解構(gòu)
let {b, c} = {a: 1. b: 2, c: 3};
b // 2
c // 3
//3、超出解構(gòu)
let {a, b, c} = {a: 1, b: 2};
a // 1
b // 2
c // undefined
//4、擴展運算符解構(gòu)
let {a, ...d} = {a: 1, b: 2, c: 3};
a // 1
d // {b: 2, c: 2}
//5、嵌套解構(gòu)
let o = {
mankind: "人類",
type: ["男人", "女人"],
act: { run: "跑步", eat: "吃飯"}
};
let {
mankind,
type: [man, woman],
act: {run, eat}
} = o;
mankind // 人類
man // 男人
woman // 女人
run // 跑步
eat // 吃飯
type // error: typeis not defined
act // error: act is not defined
// 上面的結(jié)構(gòu)是不是很相似(因為按照結(jié)構(gòu)規(guī)則去獲取值的),至于type和act為啥找不到,是因為
// 對象的解構(gòu)賦值的內(nèi)部機制,是先找到同名屬性,然后再賦給對應(yīng)的變量。
// 真正被賦值的是后者,而不是前者。這其實是一種簡寫形式。例如
// 如果變量名與屬性名一致
let {mankind: mankind} = o; 等價于 let {mankind} = o;
mankind // 人類
// 如果變量名與屬性名不一致,必須寫成下面這樣。
let {mankind: foo} = o;
foo // 人類
mankind // error: mankind is not defined
//6、默認(rèn)值
let {a = 1, b = 2, c = 3, d = 4} = {a: 5, b: undefined, c: null};
a // 5
b // 2
c // null
d // 4
// ES6 內(nèi)部使用嚴(yán)格相等運算符(===),判斷一個位置是否有值。
// 所以,只有當(dāng)一個對象成員嚴(yán)格等于undefined或者屬性值不存在時,默認(rèn)值才會生效。
//7、如果默認(rèn)值是一個表達(dá)式,那么這個表達(dá)式是惰性求值的,即只有在用到的時候,才會求值。
function f() {
console.log('aaa');
}
let [x = f()] = [1];
// 上面代碼中,因為x能取到值,所以函數(shù)f根本不會執(zhí)行。
3、Set
Set的解構(gòu)跟數(shù)組一樣也是按照嚴(yán)格的位置來解析值的。
let set = new Set();
set.add(1);
set.add(2);
let [a, b] = set;
a // 1
b // 2
4、Map
Map的解構(gòu)跟數(shù)組的嵌套解構(gòu)很相似。
let map = new Map();
map.set("a", 1);
map.set("b", 2);
let [[aKey, aVal], [bKey, bVal]] = map;
aKey // a
aVal // 1
bKey// b
bVal// 2
5、字符串
字符串同樣也是根據(jù)位置來解構(gòu)的。
let str = '12';
let [a, b] = str;
a // 1
b // 2
6、函數(shù)參數(shù)
函數(shù)參數(shù)解構(gòu)可以根據(jù)傳進(jìn)來的參數(shù)類型進(jìn)行相應(yīng)規(guī)則的解構(gòu)以及放置默認(rèn)值,參數(shù)類型可能包含數(shù)組 [1,2]、對象 {a: 1, b: 2} 、字符串 '123'等等。
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
7、無法解構(gòu)示例
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};