最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is it possible to do conditional destructuring or have a fallback? - Stack Overflow

programmeradmin1浏览0评论

I have an object that has lots of deeply nested properties. I want to be able to access properties on "MY_KEY" (below), but if that doesn't exist then get "MY_OTHER_KEY". How can I accomplish that?

const {
  X: {
    Y: {
      MY_KEY: {
        Values: segments = []
      } = {}
    } = {}
  } = {}
} = segment;

I have an object that has lots of deeply nested properties. I want to be able to access properties on "MY_KEY" (below), but if that doesn't exist then get "MY_OTHER_KEY". How can I accomplish that?

const {
  X: {
    Y: {
      MY_KEY: {
        Values: segments = []
      } = {}
    } = {}
  } = {}
} = segment;
Share Improve this question edited Aug 14, 2018 at 4:15 Gibolt 47.1k15 gold badges206 silver badges133 bronze badges asked Oct 18, 2017 at 17:39 mergesortmergesort 5,19713 gold badges40 silver badges64 bronze badges 7
  • 2 Can you include the code at Question? See stackoverflow.com/help/mcve – guest271314 Commented Oct 18, 2017 at 17:41
  • What do you mean by 'other key'? It's easy enough to check if a key is undefined, but how do you select the alternative? – kabanus Commented Oct 18, 2017 at 17:41
  • 1 Are you trying to overwrite MY_KEY with value of MY_OTHER_KEY within target if MY_KEY is undefined within source? – guest271314 Commented Oct 18, 2017 at 17:50
  • 1 Yes. And ideally succinctly rather than duplicating the destructuring. – mergesort Commented Oct 18, 2017 at 17:51
  • I'm not sure if it's that I'm unfamiliar with something here or if the code is really reductive, but this doesn't seem valid to begin with? – zfrisch Commented Oct 18, 2017 at 17:54
 |  Show 2 more comments

3 Answers 3

Reset to default 7

You could achieve this using a temporal variable inside your destructuring assignment, something like this:

function destructure(segments) {
  const {
    X: {
      Y: {
        MY_OTHER_KEY: _fallback_value = {},
        MY_KEY: {
          Values: segment = []
        } = _fallback_value,
      } = {},
    } = {},
  } = segments;

  return segment;
}

console.log(destructure({})); // []
console.log(destructure({X:{}})); // []
console.log(destructure({X:{Y:{MY_KEY:{Values:"A"}}}})); // A
console.log(destructure({X:{Y:{MY_OTHER_KEY:{Values:"B"}}}})); // B
console.log(destructure({X:{Y:{MY_OTHER_KEY:{Values:"C"}, MY_KEY:{Values:"D"}}}})); // D

First of all, this kind of destructuring will attempt to extract the second key all the time, which might have some unintended implications, like a property getter for MY_OTHER_KEY will always run.

However I fail to see the beauty in it. Hiding some control flow inside destructuring is just confusing. I would rather suggest extracting the parent object and use regular property access on it:

function destructure(segments) {
  const {
    X: {
      Y: nested = {},
    } = {},
  } = segments;
  const selected = nested.MY_KEY || nested.MY_OTHER_KEY || {};
  const {
    Values: segment = []
  } = selected;
  return segment;
}

console.log(destructure({})); // []
console.log(destructure({X:{}})); // []
console.log(destructure({X:{Y:{MY_KEY:{Values:"A"}}}})); // A
console.log(destructure({X:{Y:{MY_OTHER_KEY:{Values:"B"}}}})); // B
console.log(destructure({X:{Y:{MY_OTHER_KEY:{Values:"C"}, MY_KEY:{Values:"D"}}}})); // D

While object destructuring is cool and new, it is not the best in all cases. May do:

try {   
  var segments = segment.X.Y.MY_KEY.Values;
} catch(e){
 //whatever
}

Check if the target is defined

let {/* do destructuring stuff */}

if (MY_KEY === undefined) {
  // define `MY_OTHER_KEY` variable here
}

If you are trying to assign target to a different property if the previous target definition is undefined you can assign the variable at subsequent target definition

const segment = {Y:123};
let or = "Y";
let X;
({X, X = X || segment[or]} = segment);

console.log(X);

发布评论

评论列表(0)

  1. 暂无评论