變量的解構賦值[二對象]

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

一.對象的解構賦值

1.基本寫法

  • 基本寫法

    let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
    foo // "aaa"
    bar // "bbb"
    

2.特點

  • ① 對象屬性賦值是按照屬性名匹配的,和屬性順序無關。

    let { bar, foo } = { foo: 'aaa', bar: 'bbb' };
    foo // "aaa"
    bar // "bbb"
    
  • ② 對象解構無相應屬性,賦值爲undefined

    let {foo} = {bar: 'baz'};
    foo // undefined
    
  • ③ 對象的解構賦值可以取到繼承的屬性

    const obj1 = {};
    const obj2 = { foo: 'bar' };
    Object.setPrototypeOf(obj1, obj2);
    
    const { foo } = obj1;
    foo // "bar"
    
  • ④ 與數組一樣,解構也可以用於嵌套結構的對象。

    //一.嵌套結構
    let obj = {
      p: [
    	'Hello',
    	{ y: 'World' }
      ]
    };
    
    let { p: [x, { y }] } = obj;
    x // "Hello"
    y // "World"
    //二.這時p是模式,不是變量,因此不會被賦值。如果p也要作爲變量賦值,可以寫成下面這樣
    let obj = {
      p: [
    	'Hello',
    	{ y: 'World' }
      ]
    };
    
    let { p, p: [x, { y }] } = obj;
    x // "Hello"
    y // "World"
    p // ["Hello", {y: "World"}]
    //三.關於嵌套解構更多範例:
    //下面代碼有三次解構賦值,分別是對loc、start、line三個屬性的解構賦值。注意,最後一次對line屬性的解構賦值之中,只有line是變量,loc和start都是模式,不是變量。
    const node = {
      loc: {
    	start: {
    	  line: 1,
    	  column: 5
    	}
      }
    };
    
    let { loc, loc: { start }, loc: { start: { line }} } = node;
    line // 1
    loc  // Object {start: Object}
    start // Object {line: 1, column: 5}
    
    //嵌套賦值的例子
    let obj = {};
    let arr = [];
    
    ({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true });
    
    obj // {prop:123}
    arr // [true]
    
    // 報錯
    //下面代碼中,等號左邊對象的foo屬性,對應一個子對象。該子對象的bar屬性,解構時會報錯。原因很簡單,因爲foo這時等於undefined,再取子屬性就會報錯。
    let {foo: {bar}} = {baz: 'baz'};
    

3.對象解構賦值的本質

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

    //變量名與屬性名處理
    let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
    baz // "aaa"
    
    let obj = { first: 'hello', last: 'world' };
    let { first: f, last: l } = obj;
    f // 'hello'
    l // 'world'
    
    //如下:foo是匹配的模式,baz纔是變量。真正被賦值的是變量baz,而不是模式foo。
    
    let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
    baz // "aaa"
    foo // error: foo is not defined
    

4.對象解構賦值的使用

  • ① 將現有變量賦值給我們定義的同名變量。

    // 例一   將Math對象的對數、正弦、餘弦三個方法,賦值到對應的變量上
    let { log, sin, cos } = Math;
    
    // 例二    console.log賦值到log變量
    const { log } = console;
    log('hello') // hello
    

5.默認值

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

    var {x = 3} = {};
    x // 3
    
    var {x, y = 5} = {x: 1};
    x // 1
    y // 5
    
    var {x: y = 3} = {};
    y // 3
    
    var {x: y = 3} = {x: 5};
    y // 5
    
    var { message: msg = 'Something went wrong' } = {};
    msg // "Something went wrong"
    
  • 默認值生效的條件是,對象的屬性值嚴格等於undefined。

    var {x = 3} = {x: undefined};
    x // 3
    
    var {x = 3} = {x: null};
    x // null
    

6.解決歧義

  • 如果要將一個已經聲明的變量用於解構賦值,可能會出現歧義。

    // 一 錯誤的寫法:因爲 JavaScript 引擎會將{x}理解成一個代碼塊,從而發生語法錯誤。
    let x;
    {x} = {x: 1};
    // SyntaxError: syntax error
    
    //二 將對象放在一個圓括號裏面,解釋爲對象
    // 正確的寫法
    let x;
    ({x} = {x: 1});
    
  • 解構賦值允許等號左邊的模式之中,不放置任何變量名。因此,可以寫出非常古怪的賦值表達式。

    ({} = [true, false]);
    ({} = 'abc');
    ({} = []);
    
  • 由於數組本質是特殊的對象,因此可以對數組進行對象屬性的解構。

    let arr = [1, 2, 3];
    let {0 : first, [arr.length - 1] : last} = arr;
    first // 1
    last // 3
    
發佈了181 篇原創文章 · 獲贊 65 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章