如何解构和初始化同一表达式中缺失的嵌套字段?

How to destructure and initializing missing, nested fields in the same expression?

我一直在想弄清楚嵌套的 ES6 解构是否支持这个功能。如果 a 不存在,我想将其分配为空对象,然后将其 属性 名称 b 分配给范围变量 b.

var {
  a = {},
  a: {
    b = 2,
  },
} = {};

VM40:4 Uncaught TypeError: Cannot destructure property `b` of 'undefined' or 'null'.
    at <anonymous>:6:5

看来我不能在不假设对象格式的情况下真正嵌套解构。以下有效,但我正在寻找一种更简洁的方法,您可以在其中轻松查看原始对象的嵌套布局。

var {
  a = {},
} = {};

var {
  b = 2,
} = a;

// works as expected
// starts to look crazy when 'forking' branches that may or may not exist

您正在寻找

var {
  a: {
    b = 2,
  } = {},
//  ^^^^
} = {};

默认初始化器在目标之后(这里是内部解构表达式)。如果您希望同时初始化变量 ab,那么除了进行两个赋值之外,您无能为力:

var {
  a = {},
} = {},
{
  b = 2,
} = a;

使用两个 var 声明,这可能看起来更清晰。如果你坚持在一个嵌套表达式中做,你可以做

var {
  a = {}, // short for `a: a = {}`
  a: {
    b = 2,
  } = a, // use either `a` or another empty object as the default
} = {};

但我认为这很难读。

根据 Bergi 的回答,这就是我的最终目标。

我错过的部分是您可以初始化一个变量并在相同的整体解构中使用该变量“} = a,

(() => { 
  var {
    a: a = {
      b: {
        c: 3,
      },
    }, // if a exists, cast to a, otherwise initialize
    a: {
      b: b = {
        c: 3,
      }, // if b exists, cast to b, otherwise initialize
      b: {
        c: c = 3, // if c exists, cast to c, otherwise initialize
      } = b,
    } = a,
  } = {
    a: {
      foo: 'bar', // passes through bc spread operator, can't easily delete afaik
    },
  }; // could be destructured from any form of an object

  return {
    a: {
      ...a,
      b: {
        ...b,
        c: c,
      },
    },
  };
})();