ES6+ 解構(gòu)賦值
1. 前言
本節(jié)我們會學(xué)習(xí)到 ES6 中的解構(gòu)賦值語法,它是 JavaScript 中的一種表達(dá)式。在本節(jié)中你可以了解以下內(nèi)容:
- 什么是解構(gòu)賦值
- 數(shù)組的解構(gòu)賦值
- 對象的解構(gòu)賦值
- 如何解構(gòu)嵌套對象和數(shù)組
解構(gòu)賦值就是分解一個數(shù)據(jù)的結(jié)構(gòu),并從這數(shù)據(jù)解構(gòu)中提取數(shù)據(jù)的過程,它可以從數(shù)組中取出值賦給變量或是將對象中的屬性提取出來賦給另一個對象的屬性。解構(gòu)的目的是為了簡化提取數(shù)據(jù)的過程,增強(qiáng)代碼的可讀性。 把變量放在 []
或者 {}
中來獲取目標(biāo)對象上的對應(yīng)的值。
2. 數(shù)組的解構(gòu)賦值
2.1 基本用法
數(shù)組的解構(gòu)賦值是,通過新建一個數(shù)組,數(shù)組內(nèi)的變量和目標(biāo)數(shù)組是一一對應(yīng)的,按照索引的方式去獲取值,然后賦值給指定索引上的變量。在 ES6 之前,想獲取數(shù)組中的值,需要通過 Array[index]
的方式來獲取值,這種方式的好處在于可以獲取數(shù)組上指定索引的值,如果我們想把數(shù)組的每一項(xiàng)的值都取出來,賦給變量,這樣的寫法就顯得很笨拙:
var arr = [10, 20];
console.log(arr[0]); // 10
console.log(arr[1]); // 20
上面的取值方式是 ES6 之前的寫法,有了 ES6 的解構(gòu)賦值就簡單了很多,下面看 ES6 解構(gòu)賦值是怎么取數(shù)組的對應(yīng)值的:
var [a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20
上面的例子中先聲明一個數(shù)組,分別在數(shù)組的 0 和 1 的索引位置上放置變量 a 和 b,對應(yīng)著需要獲取數(shù)組的索引位置,這樣就可以從數(shù)組當(dāng)中取到我們想要的值了。
2.2 默認(rèn)值
在解構(gòu)一個未知的數(shù)組時,需要對未能取的值的變量賦一個默認(rèn)值,為了防止從數(shù)組中取出一個值為 undefined
的對象,可以在表達(dá)式的左邊的數(shù)組中為任意變量預(yù)設(shè)一個默認(rèn)的值。
let [a=3, b=9] = [1]; // a=1 b=9
let [a, b = 1] = [10, '']; // a=10, b=''
let [a, b = 1] = [10, undefined]; // a=10, b=1
Tips: 在 ES6 中,判斷一個數(shù)組中是否有值,使用嚴(yán)格相等運(yùn)算符(===)來進(jìn)行判斷,只有當(dāng)一個數(shù)組成員嚴(yán)格等于 undefined,默認(rèn)值才會生效。所以第三個 b 使用了默認(rèn)值。
let [a = 1] = [null]; // a=null
我們知道 null==undefined
返回的是 true,null===undefined
返回的是 false。所以數(shù)組成員是 null,默認(rèn)值就不會生效。
2.3 交換變量
在 ES6 之前如果我們想交換兩個變量的值時,我們需要借助一個中間的值來過渡,下面是要交換 a、b 值的過程:
var a = 1;
var b = 4;
var m = a;
a = b;
b = m // a=4, b=1
在交換 a、b 值時,需要借助中間的變量來中轉(zhuǎn),使用 ES6 解構(gòu)賦值就很簡單:
var a = 1;
var b = 4;
[a, b] = [b, a] // a=4, b=1
2.4 跳過某項(xiàng)值使用逗號隔開
在解構(gòu)數(shù)組時,可以忽略不需要解構(gòu)的值,可以使用逗號對解構(gòu)的數(shù)組進(jìn)行忽略操作,這樣就不需要聲明更多的變量去存值了:
var [a, , , b] = [10, 20, 30, 40];
console.log(a); // 10
console.log(b); // 40
上面的例子中,在 a、b 中間用逗號隔開了兩個值,這里怎么判斷間隔幾個值呢,可以看出逗號之間組成了多少間隔,就是間隔了多少個值。如果取值很少的情況下可以使用下標(biāo)索引的方式來獲取值。
2.5 剩余參數(shù)中的使用
通常情況下,需要把剩余的數(shù)組項(xiàng)作為一個單獨(dú)的數(shù)組,這個時候我們可以借助展開語法把剩下的數(shù)組中的值,作為一個單獨(dú)的數(shù)組,如下:
var [a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]
在 rest 的后面不能有 逗號 不然會報錯,程序會認(rèn)出你后面還有值。...rest
是剩余參數(shù)的解構(gòu),所以只能放在數(shù)組的最后,在它之后不能再有變量,否則則會報錯。
3. 對象的解構(gòu)賦值
3.1 基本用法
對象的解構(gòu)和數(shù)組基本類似,對象解構(gòu)的變量是在 {}
中定義的。對象沒有索引,但對象有更明確的鍵,通過鍵可以很方便地去對象中取值。在 ES6 之前直接使用鍵取值已經(jīng)很方便了:
var obj = { name: 'imooc', age: 7 };
var name = obj.name; // imooc
var age = obj.age; // 7
但是在 ES6 中通過解構(gòu)的方式,更加簡潔地對取值做了簡化,不需要通過點(diǎn)操作增加額外的取值操作。
var obj = { name: 'imooc', age: 7 };
var { name, age } = obj; // name: imooc, age: 7
在 {}
直接聲明 name 和 age 用逗號隔開即可得到目標(biāo)對象上的值,完成聲明賦值操作。
3.2 默認(rèn)值
對象的默認(rèn)值和數(shù)組的默認(rèn)值一樣,只能通過嚴(yán)格相等運(yùn)算符(===)來進(jìn)行判斷,只有當(dāng)一個對象的屬性值嚴(yán)格等于 undefined
,默認(rèn)值才會生效。
var {a = 10, b = 5} = {a: 3}; // a = 3, b = 5
var {a = 10, b = 5} = {a: 3, b: undefined}; // a = 3, b = 5
var {a = 10, b = 5} = {a: 3, b: null}; // a = 3, b = null
所以這里的第二項(xiàng) b 的值是默認(rèn)值,第三項(xiàng)的 null === undefined
的值為 false,所以 b 的值為 null。
3.3 重命名屬性
在對象解構(gòu)出來的變量不是我們想要的變量命名,這時我們需要對它進(jìn)行重命名。
var {a:x = 8, b:y = 3} = {a: 2};
console.log(x); // 2
console.log(y); // 3
這里把 a 和 b 的變量名重新命名為 x 和 y。
3.4 剩余參數(shù)中的使用
在對象的解構(gòu)中也可以使用剩余參數(shù),對對象中沒有解構(gòu)的剩余屬性做聚合操作,生成一個新的對象。
var {a, c, ...rest} = {a: 1, b: 2, c: 3, d: 4}
console.log(a); // 1
console.log(c); // 3
console.log(rest); // { b: 2, d: 4 }
對象中的 b、d 沒有被解構(gòu),通過剩余參數(shù)語法把沒有解構(gòu)的對象屬性聚合到一起形成新的對象。
4. 解構(gòu)字符串
當(dāng)然字符串也是可以被解構(gòu)的,字符串可以當(dāng)作數(shù)組被解構(gòu)。
const [a, b, c, d, e] = 'imooc';
console.log(a); // "i"
console.log(b); // "m"
console.log(c); // "o"
console.log(d); // "o"
console.log(e); // "c"
字符串可以被看成類數(shù)組的東西,類似數(shù)組的對象都有一個 length 屬性,字符串也可以被當(dāng)作對象來解構(gòu),但是由于字符串方法只有 length 屬性,所以只能解構(gòu)出 length 的值。
let {length : len} = 'hello';
console.log(len); // 5
5. 解構(gòu)復(fù)雜的數(shù)據(jù)結(jié)構(gòu)
了解了數(shù)組和對象的解構(gòu),下面我們看下對于復(fù)雜數(shù)據(jù)解構(gòu)應(yīng)該如何去解構(gòu)呢?看下面的例子:
var data = {
a: 1,
arr: [
{
b: 2,
c: 3
}
]
}
var {
a: newA,
arr: [
{
b: newB
}
]
} = data;
console.log(newA, newB) // 1, 2
上面的例子中 data 的數(shù)據(jù)解構(gòu)還算是比較復(fù)雜的,對于解構(gòu)這種既有對象又有數(shù)組的數(shù)據(jù)解構(gòu),我們要先聲明一個和目標(biāo)對象有著相同的數(shù)據(jù)嵌套,才能去拆解目標(biāo)對象。這里解構(gòu)的是 data 中的 a 和 b 的值,而且把 a 和 b 重命名為 newA 和 newB。
6. 小結(jié)
本節(jié)講解了 ES6 解構(gòu)賦值的使用方法,總結(jié)下來一共有以下幾點(diǎn):
- 解構(gòu)賦值一般針對對象和數(shù)組,如果解構(gòu)對象是
undefined
或是null
都會報錯; - 默認(rèn)值的生效條件是,只有當(dāng)解構(gòu)的對象的值是嚴(yán)格模式下的
undefined
的情況下,默認(rèn)值才會生效; - 可以不借助中間變量來交換兩個值;
- 在解構(gòu)復(fù)雜的數(shù)據(jù)解構(gòu)時,注意聲明的對象要和目標(biāo)的對象有著相同的解構(gòu)形式,才能去解構(gòu)目標(biāo)對象。