8

When destructuring objects in ES6 JS, you can use the { a, b } syntax in order to create new variables, called a and b respectively, from that object. However, as far as I can tell, there is no way to get the keys of the object to automatically create locally-scoped variables with those names. In the following example, I would like to be able to use the hypothetical pseudocode of const {} = args; and it would generate const a and const b automatically.

const bar = { a: 'apple', b: 'ball' };

const foo = (args) => {
  const { a, b } = args;
  console.log(a, b); // Great!
  const {} = args;   // I am aware this isn't valid syntax...
  console.log(a, b)  // Because of course, it doesn't work.
};

foo(bar);

The reason is purely because, outside of this MCVE, I'm actually using a massive object with dozens of keys, and I want to pass certain values from that across into the next part of the promise chain. I can of course use { a: args.a, b: args.b }, but I'm trying to find the shortest, cleanest way of doing this. I guess what I'm really asking for is PHP's extract()-like syntax but in ES6 JS.

Is this possible?

Ps, I'm aware that this could be seen as a very bad idea if the content of the object is untrusted.

Pps. The environment I'm testing this on is Node 7.9.0

Matt Fletcher
  • 8,182
  • 8
  • 41
  • 60
  • Not a good idea for various reasons. One of them is polluting the namespace and address space with unneeded variables – Ayush Gupta Jan 21 '18 at 16:14
  • I'm aware of why it's a bad idea, I noted that in my small print. – Matt Fletcher Jan 21 '18 at 16:15
  • Indeed, but the current options I have are horribly verbose and I'd rather not have to define the 20 or so properties I'm interested in every time I want to do something with them! It'd make linters sad because it's completely incorrect syntax :P – Matt Fletcher Jan 21 '18 at 16:18
  • 1
    Can you perhaps just pass the whole massive object along the promise chain? – Ray Toal Jan 21 '18 at 16:19
  • What is the expected result of `const {} = args;`? – guest271314 Jan 21 '18 at 16:21
  • @RayToal I am actually doing that already, and mutating it as it goes along. It's just at the last stage where those values are actually used that makes it a bit harder. But the question is meant to be a bit broader than that, really just satisfying my curiosity about whether what I'm posing is possible! – Matt Fletcher Jan 21 '18 at 16:24
  • The only way I know do to this is using the `with` statement, but because it's such a bad idea, the `with` statement is deprecated in Javascript and even forbidden in strict mode. Just use a little more typing so instead of just referencing `x`, you reference `obj.x`. – jfriend00 Jan 21 '18 at 16:24
  • What's the problem with just passing `args`? It sounds like that's exactly what you want – slebetman Jan 21 '18 at 16:24
  • @jfriend00 Ah yes I've heard horror stories about `with`. One that should be kept for esoteric code-golfy questions – Matt Fletcher Jan 21 '18 at 16:25
  • Note jfriend00's comment. Javascript already has this feature but it's such a bad idea (potential to cause bugs) that it's slowly being removed from the language – slebetman Jan 21 '18 at 16:26
  • Why do you need the variables to be distinct? Can you not simply reference the property of `args`? – guest271314 Jan 21 '18 at 16:29
  • I will probably just go with my previous method of sending a further-mutated form of the big `args` object. I was wary of doing so because it's old code I've inherited and the final function it calls has entirely different key namings, so itd mean I'd have to refactor more and more code all the time. So it was a matter of curiosity, but I'll just be less lazy. I guess the conclusion is "no, unless you want to use `with`, but you don't want to use `with`, so don't, so... no". Thanks all. Curiosity satisfied – Matt Fletcher Jan 21 '18 at 16:29
  • 1
    It's impossible without `with` but it's potential XY problem. Why exactly do you need to make them local variables if your goal is *to pass certain values from that across into the next part of the promise chain*. There may be suitable solutions for your case, possibly `pick` or else. I'd suggest to re-ask the question according to the case. – Estus Flask Jan 21 '18 at 18:37
  • I refactored the code from end to end and just passed the whole object through. But people seem to still be focused on answering the subtext of my example rather than the actual question itself... One of those dupes is an actual dupe, but one is not. Imagine I never even mentioned promises! – Matt Fletcher Jan 22 '18 at 08:24
  • No spec for it, meaning isn't jet possible. I would like to see it supported too, so it could be easily applied in modules export, etc. Object destructuring examples https://dev.to/sarah_chima/object-destructuring-in-es6-3fm – Binyamin Jan 01 '19 at 15:58

1 Answers1

1

If you want to do something with the keys but don't want to define them, why not use Object.keys or Object.entries?

const foo = (args) => {
  Object.entries(args).forEach(([key, value]) => {
    console.log(key, value);
  });
};

foo(bar);
coagmano
  • 5,542
  • 1
  • 28
  • 41