2

It is very common to have an input object that you need to copy to another object. Often you'll need to copy some of the properties, and you end up with a very similar object but with less properties.

Reference for Destructuring Assignment here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructuring

Assume you have this input object:

// an object with data
let oldObject = {
  a: 'this is a',
  b: 'this is b',
  c: 'this is c',
  d: 'this is d'
}

This is how I did it:

let myNewObject = {
  a: oldObject.a,
  b: oldObject.b,
  c: oldObject.c
}

This is the one I've been using:

// new version
let { a, b, c } = oldObject
let myNewObject = { a, b, c };

This one I'm starting to use, seems to work ok:

// newer version
let myNewObject = { a, b, c } = oldObject;

The problem with the newer versions is that I'm declaring variables a, b and c. In this case there is no problem (almost), but what if their names are input, output, temp, i or any other common name for variables that might have been already declared in the scope.

So the solution is great, but it would be even better is those variables are somehow created and destroyed in that line and not available elsewhere. myNewObject should be accessible of course.

I tried wrapping it in a function like this, but no luck at all:

let myNewObject = (function() { return { a, b, c } = oldObject })();

let myNewObject = (function() { let temp = { a, b, c } = oldObject; return temp; })();

So I'm not sure what is the best way to achieve this, I'm getting close, but I'm missing something.

nico
  • 145
  • 9
  • Possible duplicate of [One-liner to take some properties from object in ES 6](https://stackoverflow.com/questions/25553910/one-liner-to-take-some-properties-from-object-in-es-6) – Estus Flask Sep 04 '18 at 11:26

1 Answers1

2

The problem with the newer versions is that I'm declaring variables a, b and c. In this case there is no problem

There is a big problem.

let myNewObject = { a, b, c } = oldObject;

assigns to existing a, b and c variables, this will pollute global scope in loose mode or will result in error in strict mode. While myNewObject === oldObject. Its ES5 variation is:

var myNewObject = (a = oldObject.a, b = oldObject.b, c = oldObject.c, oldObject);

As explained in this answer, a one-liner you're looking for is IIFE with destructured parameter:

let myNewObject = (({ a, b, c }) => ({ a, b, c }))(oldObject);
Estus Flask
  • 150,909
  • 47
  • 291
  • 441
  • I think this solution works but writing the list of variables/properties twice is error prone, my search for this was aiming to 1. make it easier to write and 2. avoid repeating things. Any hint on how to change `let myNewObject = (({ a, b, c }) => ({ a, b, c }))(oldObject);` into something like this (of course it doesn't work) `let params = ['a', 'b', 'c']; let myNewObject = (({ ...params }) => ({ ...params }))(oldObject);` ? – nico Sep 04 '18 at 00:37
  • There's no way to write it DRYer this way. Either use existing `pick` function like Lodash or your own like shown here, https://stackoverflow.com/questions/25553910/one-liner-to-take-some-properties-from-object-in-es-6 – Estus Flask Sep 04 '18 at 11:27