-2

Let's say I'm using a method in this way:

const {a, b} = foobar()

// or...
const obj = foobar()
const {a, b} = obj

Is there a way from within the foobar function to tell whether it's result is being destructured immediately, or stored in a variable / constant? Or would it have no context at that point / in that scope, other than if you passed it in the arguments?

// Is this the only way?
const {a, b} = foobar({ isDestructured: true })
chamberlainpi
  • 4,854
  • 8
  • 32
  • 63
  • 4
    no............. – epascarello Mar 27 '23 at 12:56
  • 3
    Why would it care? What would the benefit be? I do not see a use case. – epascarello Mar 27 '23 at 12:57
  • 3
    I struggle to imagine a scenario where a function *needs* to know what is done with its return value after the function has returned. What is the actual problem you're trying to solve? – David Mar 27 '23 at 12:58
  • I understand that changing the behavior of what gets returned based on the left-side of the `=` is likely a recipe of *Bad Practice*, but mostly just curious if this is even possible, more so than actually using it in a professional project. – chamberlainpi Mar 27 '23 at 12:59
  • 2
    No, `const obj = foobar({ isDestructured: true })` would still be valid. There is no way to reliably do this. Why do you want to? Does it change the response somehow - it shouldn't. Your function shouldn't care what happens to value it returns. – phuzi Mar 27 '23 at 12:59
  • If you return `null` for example, it's not an `Object`, can't get destructured. So of course, you leave it up to the code *using* the function to handle the null-value scenario. Or you just make sure your function returns an empty object (IF you have access to modify said method) – chamberlainpi Mar 27 '23 at 13:01
  • ^ Or a classic `foobar() || {}` would do too I suppose. – chamberlainpi Mar 27 '23 at 13:02
  • @Andy thank you! Forgot to rename it in the title, fixed it everywhere else but there. Doh! – chamberlainpi Mar 27 '23 at 13:03
  • 1
    https://stackoverflow.com/questions/48433008/js-es6-destructuring-of-undefined – epascarello Mar 27 '23 at 13:10
  • 1
    There is no way that the code passes context. So you as the "architect" have to figure out what the right course of action is. Do you return an empty object, do you return an objet with defaults or do you handle null when you call the function? You pick what you think is best. – epascarello Mar 27 '23 at 13:13
  • 1
    In theory, if you really wanted to do this, and your already using some form of bundler, that in these days is pretty much the standard,. Bundlers also allow you to trans-pile, so in theory you could create an AST transformer to handle this. But I would strongly advice against it as it would make your code none-standard at the source. Transpiling JS ideally wants to act like pollyfills and only implement standards.. – Keith Mar 27 '23 at 13:20

2 Answers2

1

Is there a way from within the foobar function to tell whether it's result is being destructured immediately, or stored in a variable / constant? Or would it have no context at that point / in that scope, other than if you passed it in the arguments?

There is no way to know. A function call ends before the value can be used. The question only makes sense ifan assignment is evaluated before the function call. Yet that cannot be done, as the right-hand value is needed for the assignment.

const foo = fn();

The call fn() has to finish before foo is assigned. Thus during the execution of fn it's not possible to know what the type of assignment is. Nor should it matter. Consider:

cosnt foo = fn();

const { bar } = foo;

If bar is used consistently after this point then the code is effectively const { bar } = fn(); yet the fictional "destructuring detection" would have to flag it as not destructuring. Or would it flag the execution of fn() as being used as part of destructuring? Ultimately, that falls uder the same problem that it requires foregknowledge of how the code would execute before it does in order to determine that.

For more information:

VLAZ
  • 26,331
  • 9
  • 49
  • 67
-2

There is no such syntax to help you in JavaScript.

However, I think you can achieve what you want easily by using another function:

function thatReturnsComplexOutput() {
    return {a: 'some', b: 'thing'};
}

function thatReturnsOnlyA() {
    return thatReturnsComplexOutput().a;
}

const simpleVar = thatReturnsOnlyA();
const {a, b} = thatReturnsComplexOutput();
Nek
  • 2,715
  • 1
  • 20
  • 34