1. 程式人生 > >ES6學習之變數的解構賦值

ES6學習之變數的解構賦值

前言:什麼是ES6?ECMAScript 6(簡稱ES6)是JavaScript語言的下一代標準,已經在2015年6月正式釋出了。其中相比較於ES5新增了諸多的特性,並且ES6可轉換為ES5的語法。->線上ES6轉換為ES5工具
本系列學習隨筆參考了阮一峰老師的《ES6標準入門》

一、解構賦值簡述

在學習ES6之前,如果我們要從一個數組將值取出來,我們要如何去做?

let arr=[1,2,3];
let a=arr[0];
let b=arr[1];
let c=arr[2];

是不是感覺上面的程式碼很繁瑣,我們僅僅是從簡單的陣列結構獲取資料就需要很多重複的程式碼,若是更為複雜的資料結構呢,程式碼量可能更多,需要遍歷的次數也更多。
針對於這種情況,ES6推出瞭解構賦值,所謂的解構賦值就是允許按照一定模式,從陣列和物件中提取值,對變數進行賦值。

二、陣列的解構賦值

那我們用ES6的解構賦值可以怎麼去優化簡述中的例子呢?

let [a, b, c] = [1, 2, 3];//表示可以從陣列中提取值,按照對應的位置進行一一賦值。

同樣的效果,只需要一行程式碼,是不是更清晰與簡潔。 事實上,只要是具有Iterator 介面的都可以解構成功,關於iterable結構請關注我的部落格,後續將會介紹,或者也可以去學習阮一峰老師的《ES6標準入門》的 Iterator一章
針對於更復雜的陣列結構,也可以進行解析:

let [a, [[b], c]] = [1, [[2], 3]];//a==1,b==2,c==3
let [a,,c]=[1,2,3]//也可以只要其中幾個值a==1,c==3
let [a, ...d] = [1, 2, 3, 4];//可以用...表示這個範圍內解構成一個數組,a==1,d==[2,3,4]
let [a,b,c]=[1,2];//若是解構不成功,值為undefined,a==1,b==2,c==undefined
let [a] = 1;//若是右邊是不可遍歷結構,將會報錯。輸出Uncaught TypeError: 1 is not iterable;
let [a, b, c] = new Set([1, 2, 3]);Set結構也可以解構成功;

解構賦值中允許指定預設值:

let [a,b,c=3]=[1,2];//a==1,b==2,c==3;
//特別注意的是,當一個數組成員嚴格等於undefined,預設值才會生效。
let [a,b=2,c]=[1,null,3];//a==1,b==2,c==3;

預設值可以引用解構賦值的其他變數,但該變數必須已經宣告。

let [a=1,b=a]=[];//a==1,b==1;
let [a=b, b=1] = []; //Uncaught ReferenceError: b is not defined

三、物件的解構賦值

解構賦值不僅可以在陣列中使用,物件中也是可以的,但是物件與陣列不同的是,陣列是按照順序排列的,所以在進行物件解構賦值時,屬性名與變數一定要一樣。
接下來我們看下例子:

let {a,b}={a:1,b:2};//a==1,b==2
//若是想要屬性名與變數名不一樣,我們也可以寫成以下這樣
let { a: b } = { a: 1, c: 2 };//b==1,物件的解構賦值是先去尋找相同的屬性名再去賦值,但是真正賦值的是後者

在物件中也可以像陣列一樣進行巢狀賦值

let obj = {
  a: [
    1,
    { c: 2 }
  ]
};
let { a: [b, { c }] } = obj;//b==1,c==2
//此時a是不賦值的,若是a想賦值,可以寫成這樣
let { a, a: [b, { c }] } = obj;//a==[1,{c:2}],b==1,c==2

如果我們要對已經宣告的變數進行解構賦值,要小心js引擎將{}解析成程式碼塊:

let a;
{a} = {a: 1};//Uncaught SyntaxError: Unexpected token =
//正確的寫法如下:
({a} = {a: 1})

我們也可以有更為複雜的巢狀賦值:

let obj = {};
let arr = [];
({ b: obj.a, c: arr[0] } = { b: 1, c: 2 });//obj=={b:1},arr==[2]

我們可以引申出很多精妙的用法:

//將Math中的log,sin,cos方法逐一賦值出來。用的時候更方便。  
let { log, sin, cos } = Math;
//運算元組的結構
let arr = [1, 2, 3];
let {0 : first, [arr.length - 1] : last} = arr;

跟陣列一樣,我們在物件的解構賦值也可以進行指定預設值

var {a = 1} = {};//a==1

四、字串的解構賦值

字串也可以解構賦值:

const [a,b,c,d]=['fish'];//a=='f';b=='i';c=='s';d=='h';
//還可以解構他的屬性
const [length:len]=['fish'];//len==5

五、函式引數的解構賦值

函式的引數也能解構賦值

function add([x, y]){
  return x + y;
}
add([1, 2]); // 3

上面的例子中,一傳入引數就會自動解構賦值成x1 y2
函式引數的解構賦值也能指定預設值

function add({x = 0, y = 0} = {}) {
  return x+y;
}
add();//0
add(1);//1

六、用途

解構賦值不單單隻能用來純粹的從物件或者數組裡面取值,他還有很多精妙的用途:

let a=1;
let b=2;
[a,b]=[b,a];//此時a==2;b==1;

上面就是一個兩個變數交換值的例子,看更加起來簡潔清晰易於理解。
平時我們函式如果想返回多個變數怎麼辦?我門可以將他們先轉成陣列或者物件,然後再解構賦值:

function getArry(){
	return [1,2,3];
} 
let [a,b,c]=getArry();//a==1;b==2;c==3

利用解構賦值我們也可以將函式的多個引數一一對應起來;

function a([a,b,c]){};
a([1,2,3]);
//還可以設定函式引數的預設值,上文已提過,這裡就不重複說明了。

我們也可以利用解構賦值用來提取json裡面的值;

let json={
	data:[1,2,3]
}
const [data: num]=json;//num==[1,2,3]

總之,變數的解構賦值是ES6新增的一種使程式碼更加優美簡潔的一種模式,有興趣的同學可以多去使用學習。