3

ES6 introduced the destructuring assignment syntax that supports unpacking values from objects:

let { r = 0, g = 0, b = 0 } = { r: 255, g: 55 };
let color = { r, g, b };
console.log(color, r, g, b);  // prints "{r: 255, g: 55, b: 0} 255 55 0"

However, the following snippet would not have the same effect:

let color = { r = 0, g = 0, b = 0 } = { r: 255, g: 55 }
console.log(color);  // prints "{r: 255, g: 55}"

Same if you reverse the order:

let { r = 0, g = 0, b = 0 } = color = { r: 255, g: 55 }
console.log(color);  // prints "{r: 255, g: 55}"

Is there a one-line solution to assign r, g, b, along with color?

SimonT
  • 1,993
  • 1
  • 14
  • 29
  • 2
    No, creating a new object always requires an object literal. See also [One-liner to take some properties from object in ES6](https://stackoverflow.com/q/25553910/1048572). Your two-line version is just fine. – Bergi Oct 21 '17 at 20:07

3 Answers3

4

You could use Object.assign() first to create full color object (including all 3 parts of it), assign the result to color variable and apply the destructing on it:

let { r, g, b } = color = Object.assign({ r: 0, b: 0, g: 0 }, { r: 255, g: 55 });
console.log(r, g, b, color); // prints "255 55 0 {r: 255, b: 0, g: 55}"

Unfortunately this approach will fail in strict mode, as it's trying to assign to undefined color variable. One option to solve this, if you are fine with color being bound to window, is to assign to window.color directly (or if you are doing this inside a class/function, you can bound to this.color of course).

'use strict';

let { r, g, b } = window.color = Object.assign({ r: 0, b: 0, g: 0 }, { r: 255, g: 55 });

console.log(r, g, b, color); // prints "255 55 0 {r: 255, b: 0, g: 55}"
Martin Adámek
  • 12,431
  • 5
  • 25
  • 47
  • You don't need the Object.assign - it's equal to `let { r, g, b } = color = {r: 255, g: 55, b: 0 };`. However, the main problem is that `color` becomes a global variable (look at `window.color`). If you'll use 'strict mode', you'll get `color is undefined` error. – Ori Drori Oct 21 '17 at 23:47
  • Well the question is also about filling possibly missing key (`b`) with default value, that's the reason for Object.assign (`{r: 255, g: 55}` will be some function parameter or so probably). You are right about the global `color` variable tho... – Martin Adámek Oct 22 '17 at 09:00
1

It's not in the spirit of what you want, but you can always use a comma to write it in a single line:

'use strict';

const { r = 0, g = 0, b = 0 } = { r: 255, g: 55 }, color = { r, g, b };

console.log(color, r, g, b);
Ori Drori
  • 145,770
  • 24
  • 170
  • 162
0

This does it, but I don't believe it is what you are asking for:

let color = ({ r = 0, g = 0, b = 0 } = { r: 255, g: 55 }, {r, g, b});

As for what I believe you were expecting, I don't think is possible.

  • 1
    This throws an exception (or creates global variables in sloppy mode) when assigning to the undeclared variables. – Bergi Oct 21 '17 at 20:08