清除嵌套对象的默认方法更干净?

时间:2019-01-30 13:09:09

标签: javascript destructuring

我有一个嵌套的对象,可能缺少一些东西:

const unreliableObject = {
    id: 10,
    nestedObject: { // may be missing
        id: 11 // may also be missing
    }
}

现在说我想获取内部ID。我可以执行以下操作

const { nestedObject: { id: key = -1 } = {key: -1} } = unreliableObject;
console.log(key);

有更好的方法吗?在某些情况下,我没有两次定义{key: -1},也没有使用空对象(我们已经使用了棉绒规则),在这种情况下,我仍然想使用默认键。

1 个答案:

答案 0 :(得分:1)

如果您愿意接受类似于Lodash's get的路径符号并使用Proxy对象,则可以将p['x.y.z']转换为安全的p.x.y.z操作:

const {'x.y.z': a = 42} = path({});
const {'x.y.z': b = 42} = path({x: {}});
const {'x.y.z': c = 42} = path({x: {z: {}}});
const {'x.y.z': d = 42} = path({x: {y: {z: 999}}});

console.log(a, b, c, d);
<script>
const path = obj =>
  new Proxy(obj, {
    get(o, k) {
      const [head, ...tail] = k.split('.'); 
      return tail.length === 0 ?
        o[head] :
        path(o[head] != null ? o[head] : {})[tail.join('.')];
    }
  });
</script>


如果您不愿意使用解构并接受更多代理魔术,那么我们可以做其他疯狂的事情,例如将属性转换为功能!

const p = path(/* some object */);
p.x.y.z(42);
// either the value at 'x.y.z' or 42

const a = path({});
const b = path({x: {}});
const c = path({x: {z: {}}});
const d = path({x: {y: {z: 999}}});

console.log(a.x.y.z(42),
            b.x.y.z(42),
            c.x.y.z(42),
            d.x.y.z(42));
<script>
const path = obj =>
  new Proxy(obj, {
    get: (o, k) =>
      o[k] == null
        ? path(x => x)
        : typeof o[k] === 'object'
          ? path(o[k])
          : () => o[k] });
</script>


这可能是过度设计的,但是无论如何我还是想和Proxy一起玩;)也许这会有所帮助。