JavaScript 中物件解構時指定預設值

劉哇勇發表於2021-04-19

待解構欄位為原始值

正常情況下,

const obj = {
  a: 1,
  b: 2,
};

const { a, b } = obj;
console.log(a, b); // 1 2

當被解構欄位缺失時,

const obj = {
  a: 1,
};

const { a, b } = obj;
console.log(a, b); // 1 undefined

此時可在解構時使用 = 指定預設值:

const obj = {
  a: 1,
};

const { a, b = 2 } = obj;
console.log(a, b); // 1 2

解構時指定別名

你甚至可以在解構欄位的同時為其重新命名,

const obj = {
  a: 1,
  b: undefined
}

const { a, b: c = 2 } = obj;
console.log(a, c) // 1 2

上述過程其實為:

  • 建立變數 c
  • 獲取 obj.b 並賦值給 c
  • 如果 obj.bundefined,則將指定的預設值 2 賦值給 c

上面的過程等同於:

const c = obj.b || 2

待解構欄位為物件

考察如下的物件:

const obj = {
  innerObj: {
    a: 1,
    b: 2
  }
}

正常情況下可通過如下的形式解構以得到內層的欄位:

const obj = {
  innerObj: {
    a: 1,
    b: 2,
  },
};

const {
  innerObj: { a, b = 2 },
} = obj;

console.log(a, b); // 1 2

但如果裡面巢狀的物件缺失時,上面的解構會報錯:

const obj = {};

const {
  innerObj: { a, b = 2 },
} = obj;

console.log(a, b); // ? error: Uncaught TypeError: Cannot read property 'a' of undefined

此時需要在解構時對內層物件也指定預設值,形式如下:

const obj = {};

const {
  innerObj: { a, b = 2 } = {},
} = obj;

console.log(a, b); // undefined 2

解構欄位包含在多層巢狀內

當被解構欄位包含在多層巢狀內時,甚至可以通過上面的方式為每一層都指定預設值:

const obj = {}
const { foo: { bar: { a, b = 2 } = {} } = {} } = obj;
console.log(a, b) // undefined 2

物件解構時需要注意,當其為 null 時,上述預設值並不生效,仍會報錯。具體見下方討論。

const obj = {
  foo: {
    bar: null
  }
}
const { foo: { bar: { a, b = 2 } = {} } = {} } = obj;
console.log(a, b) // ? error: Uncaught TypeError: Cannot destructure property 'a' of '{}' as it is null.

undefined & null

上面討論的預設值僅在被解構欄位的值為 undefined 時生效。拿被解構欄位為原始為例,下面兩種情況預設值都會生效:

  • 被解構欄位缺失
const obj = {
  a: 1,
};

const { a, b = 2 } = obj;
console.log(a, b); // 1 2
  • 被解構欄位顯式地擁有 undefined
const obj = {
  a: 1
  b: undefined
}

const { a, b = 2 } = obj;
console.log(a, b) // 1 2

但如果被解構欄位的值為非 undefined 時,比如 null,此時預設值並不生效,因為欄位擁有 null 本身就是一種合法的值,所以再對其指定預設值便毫無意義。

於是,如下情況預設值不會生效:

const obj = {
  a: 1
  b: null
}

const { a, b = 2 } = obj;
console.log(a, b) // 1 null

這一規則在被解構欄位為物件時同樣適用。

The text was updated successfully, but these errors were encountered:

相關文章