4

Does JavaScript destructuring have syntax to capture both an object and its content?

In other words, can I do the following completely in the function's arg list without the following const line?

f = (a) => {
  const {b} = a;
  console.log("I see:", a, "and", b);
}

f({b:42})

==> I see {b: 42} and 42

(FWIW: I'm thinking of something like :as in Clojure or ClojureScript).

Ele
  • 33,468
  • 7
  • 37
  • 75
David Goldfarb
  • 1,796
  • 3
  • 18
  • 32
  • Not in a parameter list, no - your solution in the body is fine. In declarations you can do `const outer = a, {b} = a;` and in nested destructuring you can do `const {outer, outer: {b}} = {outer: a};` – Bergi Feb 28 '19 at 17:47

2 Answers2

5

Yes you can

const f = (a, {b} = a ) => {
  console.log("I see:", a, "and", b);
}

f({b:42})

For more use cases of destructuring assignment you can see this

On side note:- Always keep one extra parameter than you in function definition than than your function call.

Update With this way you need not to worry about one extra parameter in function definition

const f = (...z) => (a=z[0],{b}=z[0],...arguments) => {
  console.log("I see:", a, "and", b, z);
}

f({b:42},{b:32})()

You can try it with IIFE's too @bergi thanks for inputs.

const f = (a, ...z) => (({b}) => {
  console.log("I see:", a, "and", b, z);
})(a);

f({b:42},{b:32})
Code Maniac
  • 37,143
  • 5
  • 39
  • 60
  • 1
    cool trick but if you (by mistake) pass something as a second argument to the function everything breaks. It's safer to use destructuring in the function body. – marzelin Feb 28 '19 at 17:32
  • @marzelin when you intend to do something like this, means you're always aware of what you're doing ? isn't it ? – Code Maniac Feb 28 '19 at 17:34
  • @CodeManiac from my point of view doing something like this is just asking for trouble. People make mistakes unfortunately. – marzelin Feb 28 '19 at 17:36
  • 1
    -1, this is not a comma operator. It's a delimiter between multiple parameters, and should absolutely not be used here. – Bergi Feb 28 '19 at 17:46
  • No, there is no other way, but that doesn't make abusing default expressions any better. – Bergi Feb 28 '19 at 17:54
  • @Bergi anyways this still uses default expression. but it is somewhat in more intended way. is this a better way https://jsfiddle.net/oac8w52z/ – Code Maniac Feb 28 '19 at 17:57
  • 1
    @CodeManiac If you go for IIFEs as a fill-in for let expressions, I do it like this: https://jsfiddle.net/meusvptn/ :-) – Bergi Feb 28 '19 at 18:03
  • @Bergi thanks for you valuable inputs. added your suggestion as well in answer. – Code Maniac Feb 28 '19 at 18:13
0

This is a way

const f = (a, {b}=a) => {
  console.log("I see:", a, "and", b);
}

f({b:42})

The problem comes up when you need to pass more than one parameter.

const f = (a, {b}=a) => {
  console.log("I see:", a, "and", b);
}

f({b:42},123)
Ele
  • 33,468
  • 7
  • 37
  • 75
  • 1
    -1, this is not a comma operator. It's a delimiter between multiple parameters, and should absolutely not be used here. – Bergi Feb 28 '19 at 17:46