解構賦值--數組的解構賦值
什麽是解構賦值?ES6 允許按照一定模式,從數組和對象中提取值,對變量進行賦值,這被稱為解構(Destructuring)。我的理解是:允許聲明一種模式(數組、對象等),裏面包含一個或多個變量,再分別對這些變量遍歷(按照對應位置)賦值。
數組解構賦值的基本用法
以前,為變量賦值,只能直接指定值。
let a = 1;
let b = 2;
通過解構賦值:
let [a, b] = [1, 2]
這和上面分別聲明是一樣的。從後面數組中按照對應位置分別給變量賦值,允許值比變量多,稱為不完全解構,多出的部分不用管,如果變量比值多,則解構不成功,變量的值就是undefined,比如:
let [a, b, c] = [1, 2, 3, 4, 5]
a //1 b //2 c //3 而4,5就不用管了;
let [a, b, c,] = [1, 2]
a //1 b //2 c //undefined
但有一種情況,以...name這樣聲明的變量,雖然沒有對應的值,也會為其賦值空(要看前面的前面的數據類型,比如空數組或空對象):
let [a, b, ...c] = [1]
a //1 b //undefined c // []
本質上,這種寫法屬於“模式匹配”,只要等號兩邊的模式相同,左邊的變量就會被賦予對應的值。下面是一些使用嵌套數組進行解構的例子。
let [a, [[b], c]] = [1, [[2, 3], 4]];
a //1 b //2 c //4
let [ , , str] = [‘a‘, ‘b‘, ‘c‘]
str // ‘c‘
let [a, ...b] = [1, 2, 3, 4] 這中...name的形式叫做擴展運算符,後面再詳細介紹。
a //1 b //[2, 3, 4]
如果等號右邊不是數組(或者是不可以遍歷的解構,需要參考 Iterator)就會報錯,後面學習了再寫吧,先舉幾個例子:
let [a] = 1;
let [a] = false;
let [a] = NaN;
let [a] = undefined;
let [a] = null;
let [a] = {};
以上這些都會報錯,因為等號右邊的值(模式),轉換成對象後不具備 Iterator 接口(前5個),要麽本身就不具備 Iterator 接口(最後一個)。
對於 Set 結構,也可以使用數組的解構賦值:
Set結構:ES6提供的新的數據結構,它類似於數組,但是成員的值都是唯一的,沒有重復的值。Set函數可以接受一個數組(或類似數組的對象)作為參數,用來初始化。
let [x, y, z] = new Set([‘a‘, ‘b‘, ‘c‘]
x //‘a‘ y //‘b‘ z //‘c‘
事實上,只要某種數據結構具有 Iterator 接口,都可以采用數組形式的解構賦值。
function* fibs () {
let a = 0;
let b = 1;
while (true) {
yield a;
[a, b] = [b, a+b];
}
}
let [num1, num2, num3, num4, num5] = fibs();
num5 //5
上面代碼中,fibs
是一個 Generator 函數,原生具有 Iterator 接口。解構賦值會依次從這個接口獲取值。後面再詳細介紹Generator函數。
默認值
解構賦值允許指定默認值。就是在等式左邊聲明變量的時候就賦值,如果右邊有對應位置又和默認值不一樣的話,默認值就會被改變。
let [foo = true] = [];
foo //true;
let [x, y = ‘b‘] = [‘a‘];
x //‘a‘ y //‘b‘
直接在左邊聲明變量等於undefined時,右側對應位置沒有值,得到的會是undefined,如果左邊有默認值,有面對應位置是undefined,則還是取默認值,不會被undefined取代。上面說到到,如果左側只聲明為賦值,右側也沒有對應值,將取undefined。
let [x = 1] = [undefined];
x //1;
let [x = 2] = [null];
x //null
上面代碼中,如果一個數組成員是null
,默認值就不會生效,因為null
不嚴格等於undefined
。
如果默認值是一個表達式,那將會在用到時候才會求值,這個表達式稱為惰性求值。
function f () {
console.log(‘hello‘);
}
let [a = f()] = [1];
上面這個代碼,因為a能取到值,所以函數就不執行。
默認值可以引用解構賦值的其他變量,但該變量必須已經聲明。
let [x = 1, y = x] = []; x = 1; y = 1;
let [x = 1, y = x] = [2]; x = 2; y = 2;
let [x = 1, y = x] = [2, 3]; x = 2; y = 3;
let [x = y, y = 1] = [1]; ReferenceError,報錯為定義
其實就是右側有值的話,就會改變對應左側位置的變量的值,但默認值但變量需要提前聲明,否則就會報錯,就是變量第一次出現時,不能出現在‘=’右側,比如最後這個。
解構賦值--數組的解構賦值