JavaScript-ES6 神祕的解構賦值

這篇文章之前早已有“提筆畫西遊”的衝動,苦苦翻閱很多資料終於理解了神祕感十足的解構賦值,可奈何最近忙於工作上的事情擠不出時間更新博客。話不多說、先請JS祖師爺 - Douglas Crockford!

 解構賦值:ES6 允許按照一定模式,從數組和對象中提取值,對變量進行賦值,這被稱爲解構。

1、數組解構賦值:

通常定義變量並賦值的時候只能一個一個定義之後再賦值,例如:

let name = 'Destructuring'
let age = 46
let sex = '男'

而ES6允許我們藉助數組的解構賦值來這樣寫:

let [name, age, sex] = ['Destructuring——2', 46, '男']

由上述代碼可知,結構賦值本質上是根據左邊數組的索引來尋找右邊數組對應的索引、之後而賦值。

嵌套數組的解構:

let [name, [hobby], car] = ['馬雲', ['賺錢'], '奔馳-邁巴赫']
console.log(name, hobby, car) //馬雲 賺錢 奔馳-邁巴赫

空位數組的解構:如果解構不成功,變量的值就等於undefined

let [, , , age, name, hobby] = [15, 23, 32, 46]
console.log(age, name, hobby) //46 undefined undefined

 剩餘參數解構:注意剩餘參數的返回值是真數組,arguments是僞數組。

let [name, ...car] = ['馬雲', '奔馳-邁巴赫', '保時捷-911', '蘭博基尼1-大牛']
console.log(name, car) //馬雲 ["奔馳-邁巴赫", "保時捷-911", "蘭博基尼1-大牛"]

 解構失敗:若被解構的值不是可遍歷的結構,則會解構失敗導致報錯。

// 報錯
let [name] = 1;
let [name] = false;
let [name] = NaN;
let [name] = undefined;
let [name] = null;
let [name] = {};

默認參數:解構賦值時允許像函數傳參那樣攜帶默認參數。

let [name = '馬雲', sex = '女'] = [, '男']
console.log(name, sex) //馬雲 男

解構順序是先判斷等號右側數組裏面是否可以解析成功,判斷解析成功的標準有兩個:一是等號右邊必須是可遍歷的結構、二是判斷當前被解構的值是否恆等於undefined,於是就會出現下面有趣的事情:

let [name = '馬雲'] = [undefined]
name '馬雲'
let [name = '馬雲'] = [null]
name null

看到這裏,我猜你一定會在控制檯去判斷undefined == null  結果返回true,既然undefined == null 爲什麼undefined啓用了默認值,而null卻沒有啓用默認值?

原因就是 undefined == null 返回true使用的是 ==(普等) 、undefined === null返回false 而結構賦值時使用的就是 ===(恆等),既然undefined === null 爲false ,那麼就認爲null可以解構成功,所以結果name = null。

默認參數可以是一個函數?這就很有趣了,因爲可以通過傳遞函數得出擁有默認值時 先賦值默認值再去解構?還是先解構如果不成功再去賦值默認值? 或 先解構、如果成功就解構下一個?這是一個值得深思的執行順序問題,因爲我們無法從默認值是其他數據類型時判斷這個問題:

function Fn() {
    console.log('函數被調用')
    return '默認值'
}
let [Str = Fn()] = ['解構賦值']

上述代碼可以正常解構賦值,運行時 若Fn函數打印了‘函數被調用’,那執行順序就是先使用默認值、再去解構;

若Fn函數沒有打印‘函數被調用’、說明函數未被調用,直接解構成功,執行順序就是先解構 判斷是否成功、若失敗再去賦默認值;

到現在已經很明確了,解構賦值的執行順序是 先解構、若成功 則不會再去判斷默認值。失敗 纔會去啓用默認值。


2、對象解構賦值:

let { Car, Color , width } = {  Color: 'black', Car: '奔馳'}
console.log(Car,Color, width ) //奔馳 black undefined

對象結構賦值與數組解構賦值的區別在於:數組結構時是按照索引找對應值、而對象則是根據鍵名尋找對應值,且與次序無關,若鍵不存在則賦值爲undefined。

我們可以借用對象解構賦值很輕鬆的實現將window對象上的方法賦值到對應的變量上面,例如console.log()

const { log } = console
log('hello word') //hello word

是不是以後開發的時候再也不擔心拼錯console.log了?仔細想想爲什麼會這樣?

解構賦值時、等號右側是一個對象、也可以是一個對象的鍵名。window對象上的console對象裏面包含log、error等打印日誌的方法,剛好我們需要解構的鍵名是log,此時就是把console上的log方法單獨提列出來賦值給log這個變量,就是這麼 so easy!!

對象解構的難點:

引導:很多時候我們會把一個變量 轉換爲對象的形式,例如:

let lastName = "張三"
let obj = { name : lastName }
console.log(obj) //{name: "張三"}

ES6《屬性的簡潔表示法》允許在大括號裏面,直接寫入變量和函數,作爲對象的屬性和方法,根據ES6這個特效將一個變量轉換爲對象。

問題:如果變量名與屬性名不一致,必須寫成下面這樣。

let { person : lastName } = { person : '馬雲' }
console.log(lastName) //馬雲
console.log(person) //person is not defined

上述代碼左邊的person找到了右邊person的值,但是真正賦值的時候卻不是賦值給了自己,而是賦給lastName,也就是說對象的解構賦值機制是先根據等號左側的屬性名、找到右側的同名屬性,之後再賦值給對應的變量,即lastName這個變量。

未完....

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章