前言
初衷:最近在讀《深入理解Es6》這本書余耽,之前沒好好全面學(xué)過Es6語法耍缴,也是趁著不忙的階段重新好好研究一下整理一下筆記分享給大家戴而,不喜勿噴凑术。
適合人群:前端初級(jí)開發(fā),大佬繞道所意。
內(nèi)容結(jié)構(gòu):基本語法 -> 語法利弊 -> 應(yīng)用場景
為何使用解構(gòu)功能
在Es5中淮逊,我們之前要想從對(duì)象或數(shù)組對(duì)象中獲取特定的數(shù)據(jù),通常都是這么做的扶踊。來看下面例子
let person = {
name: "蛙人",
age: 24
}
let name = person.name
let age = person.age
上面example中泄鹏,可以看到我們從person
對(duì)象中獲取到name
和age
屬性并賦值給了新聲明的變量name
和age
,這樣聲明兩個(gè)變量那沒問題秧耗,假如以后多了呢备籽。
所以Es6為對(duì)象和數(shù)組提供了解構(gòu)功能,將數(shù)據(jù)結(jié)構(gòu)打散過程變得更加簡單分井,可以從打散后更小的部分獲取所需的信息车猬。下面我們來看看吧
對(duì)象解構(gòu)
let person = {
name: "蛙人",
age: 24
}
let { name, age } = person
console.log(name) // 蛙人
console.log(age) // 24
上面example中,person.name
的值被賦值給了name
變量杂抽,person.age
的值被賦值給了age
變量诈唬。只不過這里用的是對(duì)象的簡寫語法,如果不明白對(duì)象的新特性缩麸,請(qǐng)看我上一篇文章《Es6對(duì)象擴(kuò)展了哪些特性铸磅?》
不要忘記初始化值
如果使用var
、let
、const
用于聲明解構(gòu)阅仔,就必須初始化值也就是右側(cè)的變量吹散。我們來看個(gè)例子
var { name, age }; // 語法拋出錯(cuò)誤
let { name, age }; // 語法拋出錯(cuò)誤
const { name, age }; // 語法拋出錯(cuò)誤
上面example中,我們可以看到有聲明用于解構(gòu)賦值并不初始化值那么就會(huì)拋出錯(cuò)誤八酒。如果不用于解構(gòu)空民,var
和let
聲明的變量可以不用初始化值,但是const
聲明的變量必須要初始化值羞迷,否則拋出錯(cuò)誤界轩。如果不明白的var
、 let
衔瓮、const
區(qū)別浊猾,看我這篇《一看就懂的var、let热鞍、const三者區(qū)別》
注意: 如果解構(gòu)賦值右側(cè)的值為
null
orundefined
則拋出錯(cuò)誤葫慎,切記。
解構(gòu)賦值
在上面中薇宠,我們已經(jīng)把解構(gòu)說完了偷办,那么解構(gòu)賦值又是啥東西呢。就是澄港,我們同樣在給變量賦值時(shí)使用解構(gòu)語法椒涯。看下面例子
let name = "小王"
let age = 18
let person = {
name: "蛙人",
age: 24
};
// 使用解構(gòu)賦值為變量賦值
({ name, age } = person);
console.log(name) // 蛙人
console.log(age) // 24
上面example中慢睡,我們先定義了name
和age
變量逐工,并初始化值,然后又通過解構(gòu)的賦值的方法將name
和age
變量從person
對(duì)象中讀取重新賦值漂辐。注意泪喊,一定要用一對(duì)小括號(hào)包裹解構(gòu)賦值語句
,JavaScript
引擎會(huì)把花括號(hào)當(dāng)成一個(gè)代碼塊髓涯,而語法規(guī)定代碼塊不能出現(xiàn)在賦值語句的左側(cè)袒啼,用小括號(hào)包裹后可以將代碼塊轉(zhuǎn)換成一個(gè)表達(dá)式,這樣可以實(shí)現(xiàn)解構(gòu)賦值啦纬纪。
我們接下來蚓再,在函數(shù)參數(shù)使用解構(gòu)賦值表達(dá)式
let name = "小王"
let age = 18
let person = {
name: "蛙人",
age: 24
};
function getObj(data) {
console.log(data == person) // true 這里的data就是person,表達(dá)式的值就是 =右側(cè)的的值
}
getObj({ name, age } = person)
console.log(name) // 蛙人
console.log(age) // 24
上面example中包各,調(diào)用getObj
函數(shù)時(shí)傳入了一個(gè)解構(gòu)賦值表達(dá)式摘仅,由于JavaScript
表達(dá)式的值為右側(cè)的值,所以函數(shù)里的參數(shù)對(duì)象就是person
對(duì)象问畅,并且也將name
和age
變量重新賦值娃属。
使用解構(gòu)賦值時(shí)六荒,如果指定的變量名稱在對(duì)象中不存在,那么這個(gè)變量就是undefined
的矾端。來看下面例子
let person = {
name: "蛙人",
age: 24
}
let { name, age, sex} = person;
console.log(name, age, sex) // 蛙人 24 undefined
上面example中掏击,解構(gòu)賦值表達(dá)式里有個(gè)sex
變量,但是顯然對(duì)象里不存在這個(gè)sex
屬性秩铆,這時(shí)這個(gè)sex
變量就會(huì)被賦值于undefined
砚亭。
當(dāng)指定的屬性不存在時(shí),我們可以設(shè)置一個(gè)默認(rèn)值殴玛,跟函數(shù)參數(shù)默認(rèn)值一樣捅膘。來看下面例子
let person = {
name: "蛙人",
age: 24
}
let { name, age, sex = "male" } = person;
console.log(name, age, sex) // 蛙人 24 male
上面example中,給sex
設(shè)置默認(rèn)值族阅,只有當(dāng)person
對(duì)象上沒有該屬性時(shí)或這個(gè)屬性為undefined時(shí)篓跛,這個(gè)默認(rèn)值才會(huì)生效,這和函數(shù)默認(rèn)值一樣坦刀,如有不明白可以看我這篇文章《你真的了解ES6中的函數(shù)特性么?》蔬咬。
解構(gòu)賦值起別名
以上代碼中鲤遥,我們解構(gòu)表達(dá)式都是同變量同屬性名,那么有時(shí)候我們解構(gòu)出來的不想和這個(gè)屬性名稱一樣林艘,怎么辦呢盖奈,解構(gòu)表達(dá)式同意支持起別名。來看下面例子
let person = {
name: "蛙人",
age: 24
}
let { name: userName, age: userAge } = person
console.log(userName) // 蛙人
console.log(userAge) // 24
上面example中狐援,上面解構(gòu)表達(dá)式中將name
屬性存儲(chǔ)在了userName
钢坦,將age
屬性存儲(chǔ)在了userAge
,那么這時(shí)就不能訪問name
和age
了啥酱,因?yàn)樗麄z已經(jīng)不是變量了爹凹。
解構(gòu)賦值起別名也支持默認(rèn)參數(shù)
let person = {
name: "蛙人",
age: undefined
}
let { name: userName, age: userAge = 24 } = person
console.log(userName) // 蛙人
console.log(userAge) // 24
這里就不多說了,跟上面說的默認(rèn)參數(shù)是一樣的道理镶殷。
對(duì)象多層嵌套解構(gòu)
解構(gòu)賦值也支持多層嵌套禾酱,語法跟上面講的對(duì)象字面量也一樣,可以更加細(xì)化的拆分解構(gòu)绘趋。來看下面例子
let person = {
name: "蛙人",
age: 24,
hobby: {
name: "寫代碼"
}
}
let { hobby: { name: code = "code" } } = person
console.log(code) // 寫代碼
上面example中颤陶,可以看到上面多層解構(gòu)語法跟普通解構(gòu)是一樣的,只不過在嵌套一層{}
花括號(hào)而已陷遮。上面我們已經(jīng)解構(gòu)出來hobby
屬性滓走,然后繼續(xù)往里深入解構(gòu)name
屬性并且賦予默認(rèn)值,然后我們又給它起了個(gè)別名變量code
帽馋。
對(duì)象解構(gòu)雷區(qū)需注意
在使用多層嵌套解構(gòu)時(shí)需要注意搅方,你很有可能無意間創(chuàng)建了一個(gè)無效的表達(dá)式比吭,就是解構(gòu)空花括號(hào)但是這個(gè)語法也是合法的,也什么都不會(huì)做腰懂,也不報(bào)錯(cuò)梗逮。下面我們來看一下。
let person = {
name: "蛙人",
age: 24,
hobby: {
name: "寫代碼"
}
}
let { hobby: {} } = person
在上面語句中绣溜,可以看到深層解構(gòu)hobby
屬性右側(cè)是一個(gè){}
括號(hào)慷彤,但沒有聲明任何變量,這個(gè)語句也是合理的且不會(huì)報(bào)錯(cuò)怖喻。官方回答:這個(gè)語法在將來有可能被廢棄掉底哗,咱們只要知道別這樣寫就行。
數(shù)組解構(gòu)
數(shù)組解構(gòu)語法跟對(duì)象解構(gòu)語法差不多锚沸,只不過數(shù)組解構(gòu)用[]
字面量語法解構(gòu)跋选,看下面例子。
let colors = ["red", "blue", "green"]
let [ red, blue ] = colors
console.log(red, blue) // red blue
數(shù)組解構(gòu)和對(duì)象解構(gòu)最大的區(qū)別哗蜈,對(duì)象解構(gòu)無序的而數(shù)組解構(gòu)是有序的前标,我們來看下例子。
let colors = ["red", "blue", "green"];
let [ blue ] = colors
console.log(blue) // red
let ObjColors = {
red: "red",
blue: "blue",
green: "green"
}
let { blue } = objColors
console.log(blue) // blue
上面example中距潘,我們可以看到數(shù)組解構(gòu)的blue
變量是red
值炼列,所以數(shù)組解構(gòu)是根據(jù)位置來的,一個(gè)位置對(duì)應(yīng)一個(gè)值音比,不能像對(duì)象字面量那樣對(duì)象里面有值我們就可以直接獲取出來俭尖,不需要按照順序。而數(shù)組解構(gòu)是需要的順序解構(gòu)的洞翩。
如果我們只想獲取數(shù)組第二個(gè)值稽犁,我們可以直接忽略第一個(gè)值的變量,只寫一個(gè)占位符就可以骚亿。來看下面例子
let colors = ["red", "blue", "green"]
let [ , blue ] = colors
console.log(blue) // blue
上面example中已亥,只獲取第二個(gè)值,所以把數(shù)組解構(gòu)第一個(gè)值只占位不聲明變量循未,然后在寫入blue
變量陷猫,這樣就可以只獲取第二個(gè)值了。
數(shù)組解構(gòu)跟對(duì)象解構(gòu)一樣的妖,var绣檬、let、const聲明的數(shù)組解構(gòu)必須都要初始化值嫂粟,否則拋出錯(cuò)誤娇未。上面將對(duì)面解構(gòu)時(shí)已說過,切記星虹。
數(shù)組解構(gòu)默認(rèn)值
數(shù)組解構(gòu)默認(rèn)值跟對(duì)象解構(gòu)默認(rèn)值也是一樣的零抬,只要數(shù)組里面沒有這個(gè)值或者這個(gè)值被設(shè)置為undefined
那么默認(rèn)值就會(huì)生效镊讼。
let person = ["蛙人", 24]
let [ name, age, sex = "male" ] = person
console.log(name, age, sex) // 蛙人 24 male
數(shù)組多層嵌套解構(gòu)
數(shù)組多層嵌套解構(gòu)跟對(duì)象多層嵌套解構(gòu)也是類似,就是語法不一樣平夜,數(shù)組使用[]
按照順序解構(gòu)蝶棋。我們來看一下例子
let person = ["蛙人", 24, ["寫代碼", "撩妹", "羽毛球"]]
let [ name, age, [firstHobby] ] = person
console.log(name, age, firstHobby) // 蛙人 24 寫代碼
上面example中,可以看到多層解構(gòu)時(shí)忽妒,使用[]
方括號(hào)往里一層一層深入玩裙,層層抽取我們想要的數(shù)據(jù)。
數(shù)組解構(gòu)和對(duì)象解構(gòu)語法都差不多類似段直,只需要注意數(shù)組解構(gòu)使用[]
吃溅,對(duì)象解構(gòu)使用{}
,及他們的雷區(qū)也都是一樣的鸯檬,我使用解構(gòu)那就必須得初始化右側(cè)的值决侈,否則報(bào)錯(cuò)。
混合解構(gòu)
以上講完了喧务,上面都是說的單一對(duì)象解構(gòu)赖歌,那么我們現(xiàn)在可以做一些混合解構(gòu),這就要數(shù)據(jù)解構(gòu)和對(duì)象解構(gòu)都要用上了功茴∏握荆看下面例子
let person = {
name: "蛙人",
age: 24,
sex: "male",
hobby: ["寫代碼", "撩妹", "羽毛球"]
}
let { name, sex, hobby: [, , lastHobby] } = person
console.log(name, sex, lastHobby) // 蛙人 male 羽毛球
上面example中,person
是一個(gè)對(duì)象痊土,里面定義了個(gè)人信息。然后到下面解構(gòu)時(shí)墨林,里面用到了對(duì)象解構(gòu)和數(shù)組解構(gòu)赁酝,然后我們知道數(shù)組解構(gòu)只能根據(jù)位置來解構(gòu),所以使用數(shù)組占位符獲取出來最后一個(gè)數(shù)組的值旭等。
那么上面講了這么多語法酌呆,到底用在哪呢?什么樣的場景下使用呢搔耕?下面就來看一下這些語法應(yīng)用場景
應(yīng)用場景
對(duì)象解構(gòu)
通常在Es5中隙袁,比如我們要做一個(gè)個(gè)人信息信息展現(xiàn)功能,我們先寫個(gè)函數(shù)然后傳遞一個(gè)對(duì)象弃榨,在這個(gè)函數(shù)里面我們需要聲明賦值一堆變量菩收,而這些值都從傳遞進(jìn)來的那個(gè)對(duì)象里面去取。來看下面例子
function informationFn(data) {
let name = data.name;
let age = data.age;
let sex = data.sex;
let email = data.email;
let phone = typeof data.phone != "undefined" ? data.phone : "暫無";
}
let person = {
name: "蛙人",
age: 24,
sex: "男",
email: "xxxxxx@163.com",
phone: undefined
}
informationFn(person)
上面example中鲸睛,可以看到代碼雖然沒有問題娜饵,但是這樣一來代碼太多,造成代碼冗余官辈,現(xiàn)在我們?cè)谟肊s6語法來實(shí)現(xiàn)一下上面功能箱舞。
function informationFn({ name, age, sex, email, phone = "暫無" }) {
console.log(name, age, sex, email, phone)
}
let person = {
name: "蛙人",
age: 24,
sex: "男",
email: "xxxxxx@163.com",
phone: undefined
}
informationFn(person)
上面example中遍坟,是我們用Es6語法對(duì)象解構(gòu)和解構(gòu)默認(rèn)值又實(shí)現(xiàn)了一下,可以看到代碼非常簡潔晴股。
數(shù)組解構(gòu)及賦值
在Es5中愿伴,我們想要實(shí)現(xiàn)一個(gè)兩個(gè)變量互相交換值,還得依靠第一個(gè)變量來實(shí)現(xiàn)电湘。
let a = 1;
let b = 2;
let temp;
temp = a;
a = b;
b = temp;
console.log(a, b) // 2 1
然而在Es6出現(xiàn)數(shù)組解構(gòu)賦值隔节,完全不需要這么做,我們來看下怎么實(shí)現(xiàn)胡桨。
let a = 1;
let b = 2;
[ a, b ] = [b, a]
console.log(a, b)
上面example中官帘,解構(gòu)賦值右側(cè)表達(dá)式,是臨時(shí)組建的數(shù)組昧谊,它會(huì)先計(jì)算右側(cè)數(shù)組刽虹,最后在將右側(cè)數(shù)組賦值于前面數(shù)組變量。
感謝
謝謝各位在百忙之中點(diǎn)開這篇文章呢诬,希望對(duì)你們能有所幫助涌哲,如有問題歡迎各位大佬指正。
如果覺得寫得還行的話尚镰,那就點(diǎn)個(gè)贊吧阀圾。
有興趣的話大家也可以加我的個(gè)人vx進(jìn)行交流 聯(lián)系我