變量的解構賦值
ES6 允許按照一定模式,從數組和對象中提取值,對變量進行賦值,這被稱爲解構。
1. 數組的解構賦值
以前爲變量賦值,只能直接指定值。
// 直接指定值
let a = 1;
let b = 2;
let c = 3;
ES6 允許通過解構進行賦值。
let [a, b, c] = [1, 2, 3];
a; // 1
b; // 2
c; // 3
上面代碼中,a
,b
,c
三個變量,按照數組中對應位置上的值被賦值。
還可以對嵌套數組進行解構賦值。
// 對嵌套數組進行解構賦值
let [x, [[y], z]] = [1, [[2], 3]];
x; // 1
y; // 2
z; // 3
// 對數組部分數據進行解構賦值
let [ , , third] = ["hello", "world", "!"];
third // "!"
let [x, ...y] = [1, 2, 3, 4];
x; // 1
y; // [2, 3, 4]
解構不成功,變量的值就等於undefined
。
let [x, y] = ['a'];
x; // "a"
y; // undefined
let [x] = [];
let [y, z] = [1];
x; // undefined
y; // 1
z; // undefined
注意:
ES6 內部使用嚴格相等運算符(===
),判斷一個位置是否有值。所以,只有當一個數組成員嚴格等於undefined
,默認值纔會生效。
不完全解構,即等號左邊的模式,只匹配一部分的等號右邊的數組。解構依然成功。
let [x, y] = [1, 2, 3, 4];
x; // 1
y; // 2
// 嵌套數組不完全解構
let [a, [b], d] = [1, [2, 3], 4];
a; // 1
b; // 2
d; // 4
默認值
解構賦值允許指定默認值。
// 指定默認值
let [flag= true] = [];
foo; // true
let [x, y = 'b'] = ['a'];
x; // 'a'
y; // 'b'
let [x, y = 'b'] = ['a', undefined];
x; // 'a'
y; // 'b'
默認值可以是一個表達式,但是這個表達式是惰性求值的,即只有在用到的時候,纔會求值。
function f() {
return 'Hello World!'
}
let [x = f()] = [1];
x; // 結果爲1,函數不會執行
默認值可以引用解構賦值的其他變量,但該變量必須已經聲明。
let [x = 1, y = x] = []; // x=1; y=1
let [x = y, y = 1] = []; // ReferenceError: y is not defined
2. 對象的解構賦值
對象也可以進行解構賦值。
let { name, age} = { name: 'jidi', age: 22 };
name; // "jidi"
age; // 22
對於對象的解構,變量名次序不必像數組一樣保持一致(數組元素按照次序排列,位置決定取值),只要變量與屬性同名,才能取到正確的值,否則會取不到值,返回undefined
。
let { name, age} = { age: 22, name: 'jidi' };
name; // "jidi"
age; // 22
// 對象屬性中找不到與變量名一致的屬性,則值爲undefined
let { sex} = { name: 'jidi', age: 22 };
sex; // undefined
對象解構賦值失敗,變量的值爲undefined
。
let { sex} = { name: 'jidi' };
sex; // undefined
對象解構賦值允許變量名與屬性名不一致,但是必須寫成下面樣子。
let { name: xingming } = { name: 'jidi' };
xingming; // "jidi"
let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f; // 'hello'
l; // 'world'
對象的解構賦值也可以用於具有嵌套結構的對象。
let person = {
man: [
{ sex: '男' }
],
woman: [
{ sex: '女' }
]
};
let { man: [{ x }], woman: [{ y }]} = person;
x; // { sex: '男' }
y; // { sex: '女' }
上述例子中,man
和woman
此時不是變量,而是模式,不會被賦值。如果也要被賦值,需要寫成下面樣子。
let { man, man: [{ x }], woman, woman: [{ y }]} = person;
下面是另一個例子。
const example= {
first: {
second: {
name: 'jidi',
age: 22
}
}
};
let { first, first:{ second }, first:{ second: name }, first:{ second: age }} = example;
first; // { second: { name: 'jidi', age: 22 }}
second; // { name: 'jidi', age: 22 }
name; // 'jidi'
age; // 22
對象的解構賦值可以取到繼承的屬性。
const x= {};
const y= { name: 'jidi' };
// 將對象y設置爲對象x的原型對象,對象x會繼承原型對象y的屬性name
Object.setPrototypeOf(x, y);
const { name} = x;
name; // 'jidi'
默認值
對象的解構也可以指定默認值。默認值生效的條件是,對象的屬性值嚴格等於undefined
。
var { x = 3 } = {};
x; // 3
var {x, y = 5} = {x: 1};
x // 1
y // 5
注意:
由於數組是一個特殊的對象,因此可以對數組進行對象屬性的解構。
let arr = [1, 2, 3];
let { 0 : first, [arr.length - 1] : last, length } = arr;
first; // 1
last; // 3
length; // 3
3. 字符串的解構賦值
也可以對字符串進行解構賦值,可以把字符串看成是一個類似數組的對象。
const [x, y, z] = 'you';
x; // 'y'
y; // 'y'
z; // 'u'
4. 數值和布爾值的解構賦值
解構賦值時,如果等號右邊是數值和布爾值,則會先轉爲對象。
let { toString: s } = 123;
s === Number.prototype.toString; // true
let { toString: s } = true;
s === Boolean.prototype.toString; // true
注意:
對undefined
和null
進行解構賦值,都會報錯。
5. 函數參數的解構賦值
函數的參數也可以使用解構賦值。
// 例子一
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
// 例子二
[[1, 2], [3, 4]].map(([a, b]) => a + b); // [ 3, 7 ]
函數參數的解構也可以使用默認值。
function move({ x = 0, y = 0 } = {} ) {
return [x, y];
}
move({ x: 3, y: 8 }); // [3, 8]
move({ x: 3 }); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]
6. 參考鏈接
本篇博文是我自己學習筆記,原文請參考:ECMAScript 6 入門
如有問題,請及時指出!
歡迎溝通交流,郵箱:[email protected]。