ES 6 : 變量的解構賦值


1. 數組的解構賦值

[ 基本用法 ]

  按照一定的模式從數組或者對象中取值,對變量進行賦值的過程稱為解構。

  以前,為變量賦值只能直接指定值:

  而ES 6 允許寫成下面這樣:

  上面的代碼表示,可以從數組中取值,按照位置的對應關系對變量賦值。

 [ 默認值 ] 

  解構賦值允許使用默認值。

  ES6內部使用嚴格相等運算符(===)判斷一個位置是否有值。所以,如果一個數組成員不嚴格等於undefined,默認值是不會生效的。

  上述代碼中,一個數組成員是null,因此默認值不生效。因為null不嚴格等於undefined。

  如果默認值是一個表達式,那么這個表達式是惰性求值的,即只有在用到的時候才會求值。

2.對象的解構賦值

  

  對象的解構賦值與數組有一個不同,數組的元素是按次序排列的,變量的取值由它的位置決定;而對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值。

  上面代碼中,變量沒有對應的同名屬性,導致取不到值,最后等於undefined。

  實際上,對象的解構賦值是以下形式的簡寫:

var { foo: foo, baz: baz } = { foo:"aaa", baz:"bbb" }

  也就是說,對象的解構賦值的內部機制,是先找到同名屬性,然后再賦給對應的變量。真正被賦值的是后者,而不是前者。

  采用這種寫法時,變量的聲明和賦值是一體的。對於let和const而言,變量不能重新聲明,所以一旦賦值的變量以前聲明過,就會報錯。

  上述代碼沒有第二個let命令就不會報錯:

  和數組一樣,解構也可以用於嵌套結構的對象。

  對象的解構也可以指定默認值。

  默認值生效的條件是,對象的屬性值嚴格等於undefined。

  如果解構模式是嵌套的對象,而且子對象所在的父屬性不存在,那么將會報錯。

 

  這時foo的值是undefined所以再取子對象會報錯。

3.字符串的解構賦值

  字符串的解構賦值機制是將字符串轉換成一個類似數組的對象:

  類似數組的對象都有length屬性,因此還可以對這個屬性解構賦值:

4.數值和布爾值的解構賦值

  解構賦值的規則是:只要等號右邊的值不是對象,就先將其轉為對象。

5.函數參數的解構賦值

  上面代碼中,函數add的參數實際上不是一個數組,而是通過解構得到的變量x和y。

   函數參數的解構也可以使用默認值。

  上面的代碼中,函數move的參數是一個對象,通過對這個對象進行解構,得到變量x和y的值。如果解構失敗,則x和y等於默認值。

  注意:下面的寫法會得到不一樣的結果。

6.圓括號問題

  解構賦值雖然很方便,但是解析並不容易。對於編譯器來說,一個式子到底是模式還是表達式,沒有辦法從一開始就知道,必須解析到(或解析不到)等號才能知道。由此帶來的問題是,模式中出現圓括號怎么處理,ES6的規則是,只要有可能導致解構歧義,就不得使用圓括號。

[ 不能使用圓括號的情況 ]

  以下3種解構賦值不得使用圓括號:

  - 變量聲明語句中,模式不能帶有圓括號。

  

  上面3條語句都會報錯,因為它們都是變量聲明語句,模式不能使用圓括號。

  - 函數參數中,模式不能帶有圓括號。

  函數參數也屬於變量聲明,因此不能帶有圓括號。

  

  - 不能將整個模式或嵌套模式中的一層放在圓括號中。

  

  上面的代碼將整個模式放在了圓括號中,導致報錯。

  

  上面的代碼將嵌套模式的一層放在了圓括號中,導致報錯。

[ 可以使用圓括號的情況 ]

  可以使用圓括號的情況只有一種:賦值語句的非模式部分可以使用圓括號

  

7.用途

[ 交換變量的值 ]

  [x, y] = [y, x]

  上面的代碼交換了x和y的值,這樣的寫法不僅簡潔,而且易讀,語義非常清晰。

[ 從函數返回多個值 ]

  函數只能返回一個值,如果要返回多個值,只能將其放在數組或對象中返回。有了解構賦值,取出這些值就非常方便。

  // 返回一個數組

  

  // 返回一個對象

  

[ 函數參數的定義 ]

  解構賦值可以方便地將一組參數與變量名對應起來。

// 參數是一組有次序的值
function f([x,y,z]) {...}
f([1,2,3])
// 參數是一組無次序的值
function f([x,y,z]) {...}
f({z: 3, y: 2, x: 1})

[ 提取JSON數據 ]

  解構賦值對提取JSON對象中的數據尤其有用。

  

[ 函數參數的默認值 ]

jQuery.ajax = function (url,{
    async = true,
    beforeSend = function(){},
    cache = true,
    complete = function(){},
    crossDomain = false,
    global = true,
    // ... more config
}){
    // ... do stuff
}

  指定參數的默認值,就避免了在函數體內部再寫var foo = config.foo || 'default foo';這樣的語句。

[ 遍歷Map解構 ]

  任何部署了Iterator接口的對象,都可以用for...of循環遍歷。Map結構原聲支持Iterator接口,配合變量的解構賦值,獲取鍵名和鍵值就非常方便。

  如果只是想獲取鍵名,或者只是想獲取鍵值,可以寫成下面這樣:

// 獲取鍵名
for (let [key] of map) {
    // ...
}   

// 獲取鍵值
for (let [value] of map) {
    // ...
}   

[ 輸入模塊的指定方法 ]

  加載模塊時,往往需要指定輸入哪些方法。解構賦值使得輸入語句非常清晰。

const { SourceMapConsumer, SourceNode} = require("source-map")

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM