解構(gòu):使數(shù)據(jù)訪問更便捷荚孵!

前言

初衷:最近在讀《深入理解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ì)象中獲取到nameage屬性并賦值給了新聲明的變量nameage,這樣聲明兩個(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ò)展了哪些特性铸磅?》

不要忘記初始化值

如果使用varletconst用于聲明解構(gòu)阅仔,就必須初始化值也就是右側(cè)的變量吹散。我們來看個(gè)例子

var { name, age }; // 語法拋出錯(cuò)誤
let { name, age }; // 語法拋出錯(cuò)誤
const { name, age }; // 語法拋出錯(cuò)誤

上面example中,我們可以看到有聲明用于解構(gòu)賦值并不初始化值那么就會(huì)拋出錯(cuò)誤八酒。如果不用于解構(gòu)空民,varlet聲明的變量可以不用初始化值,但是const聲明的變量必須要初始化值羞迷,否則拋出錯(cuò)誤界轩。如果不明白的varlet衔瓮、const區(qū)別浊猾,看我這篇《一看就懂的var、let热鞍、const三者區(qū)別》

注意: 如果解構(gòu)賦值右側(cè)的值為null or undefined則拋出錯(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中慢睡,我們先定義了nameage變量逐工,并初始化值,然后又通過解構(gòu)的賦值的方法將nameage變量從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ì)象问畅,并且也將nameage變量重新賦值娃属。

使用解構(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í)就不能訪問nameage了啥酱,因?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)系我

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市狗唉,隨后出現(xiàn)的幾起案子初烘,更是在濱河造成了極大的恐慌,老刑警劉巖分俯,帶你破解...
    沈念sama閱讀 211,376評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肾筐,死亡現(xiàn)場離奇詭異,居然都是意外死亡缸剪,警方通過查閱死者的電腦和手機(jī)吗铐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來杏节,“玉大人唬渗,你說我怎么就攤上這事》苡妫” “怎么了镊逝?”我有些...
    開封第一講書人閱讀 156,966評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長卒稳。 經(jīng)常有香客問我蹋半,道長,這世上最難降的妖魔是什么充坑? 我笑而不...
    開封第一講書人閱讀 56,432評(píng)論 1 283
  • 正文 為了忘掉前任减江,我火速辦了婚禮染突,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘辈灼。我一直安慰自己份企,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評(píng)論 6 385
  • 文/花漫 我一把揭開白布巡莹。 她就那樣靜靜地躺著司志,像睡著了一般。 火紅的嫁衣襯著肌膚如雪降宅。 梳的紋絲不亂的頭發(fā)上骂远,一...
    開封第一講書人閱讀 49,792評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音腰根,去河邊找鬼激才。 笑死,一個(gè)胖子當(dāng)著我的面吹牛额嘿,可吹牛的內(nèi)容都是我干的瘸恼。 我是一名探鬼主播,決...
    沈念sama閱讀 38,933評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼册养,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼东帅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起球拦,我...
    開封第一講書人閱讀 37,701評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤靠闭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后坎炼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體阎毅,經(jīng)...
    沈念sama閱讀 44,143評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評(píng)論 2 327
  • 正文 我和宋清朗相戀三年点弯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片矿咕。...
    茶點(diǎn)故事閱讀 38,626評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡抢肛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出碳柱,到底是詐尸還是另有隱情捡絮,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評(píng)論 4 329
  • 正文 年R本政府宣布莲镣,位于F島的核電站福稳,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏瑞侮。R本人自食惡果不足惜的圆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評(píng)論 3 313
  • 文/蒙蒙 一鼓拧、第九天 我趴在偏房一處隱蔽的房頂上張望筐咧。 院中可真熱鬧畦戒,春花似錦、人聲如沸雀瓢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至阎抒,卻和暖如春酪我,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背且叁。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工都哭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人谴古。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓质涛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親掰担。 傳聞我的和親對(duì)象是個(gè)殘疾皇子汇陆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容