天天看點

ES6學習筆記之變量的解構指派——對象的解構指派

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

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

對象的解構指派,可以很友善地将現有對象的方法,指派到某個變量。

// 例一
let { log, sin, cos } = Math;
// 例二
const { log } = console;
log('hello') // hello
           

上面代碼的例一将Math對象的對數、正弦、餘弦三個方法,指派到對應的變量上,使用起來就會友善很多。例二将console.log指派到log變量。

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

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'
           

這實際上說明,對象的解構指派是下面形式的簡寫

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

上面代碼中,foo是比對的模式,baz才是變量。真正被指派的是變量baz,而不是模式foo。

解構也可以用于嵌套結構的對象:

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 {foo: {bar}} = {baz: ‘baz’};

上面代碼中,等号左邊對象的foo屬性,對應一個子對象。該子對象的bar屬性,解構時會報錯。原因很簡單,因為foo這時等于undefined,再取子屬性就會報錯。

注意,對象的解構指派可以取到繼承的屬性。

const obj1 = {};
const obj2 = { foo: 'bar' };
Object.setPrototypeOf(obj1, obj2);

const { foo } = obj1;
foo // "bar"
           

上面代碼中,對象obj1的原型對象是obj2。foo屬性不是obj1自身的屬性,而是繼承自obj2的屬性,解構指派可以取到這個屬性。

對象的解構也可以指定預設值。預設值生效的條件是,對象的屬性值嚴格等于undefined。和數組預設值一樣。

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

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

上面代碼中,屬性x等于null,因為null與undefined不嚴格相等,是以是個有效的指派,導緻預設值3不會生效。

**

注意:

**

(1)如果要将一個已經聲明的變量用于解構指派,必須非常小心。

// 錯誤的寫法
let x;
{x} = {x: 1};
// SyntaxError: syntax error
           

上面代碼的寫法會報錯,因為 JavaScript 引擎會将{x}了解成一個代碼塊,進而發生文法錯誤。隻有不将大括号寫在行首,避免 JavaScript 将其解釋為代碼塊,才能解決這個問題。

// 正确的寫法
let x;
({x} = {x: 1});
           

(2)解構指派允許等号左邊的模式之中,不放置任何變量名。是以,可以寫出非常古怪的指派表達式。下面的表達式雖然毫無意義,但是文法是合法的,可以執行。

({} = [true, false]);
({} = 'abc');
({} = []);
           

(3)由于數組本質是特殊的對象,是以可以對數組進行對象屬性的解構。

let arr = [1, 2, 3];
let {0 : first, [arr.length - 1] : last} = arr;
first // 1
last // 3
           

繼續閱讀