Im trying to figure out what is the best way to achieve a reconstructed "destructured" shallow copy of an object. I mean, how can I get a referenced object with only a subset of keys, but who are connected to the original object? From let original={ a=1, b=2, c=3}
to a reference connected let reconstructed= { a=1, c=3}
... values of keys are strings or numbers. I tried workarounds but cannot get a comfortable solution for this. Help would be appreciated.

- 3
- 1
-
1Please post JavaScript as a [mcve] – zer00ne May 05 '22 at 16:31
-
In a shallow copy the properties are not linked to the original object. That's the meaning of shallow copy. `reconstructed.a` and `reconstructed.c` are copies of `original.a` resp. `original.c`. – jabaa May 05 '22 at 16:33
-
1just use `JSON.parse(JSON.stringify(obj))` – R4ncid May 05 '22 at 16:35
-
@R4ncid That's the opposite the OP asks for. OP wants `reconstructed.a` to reference `original.a`: _"I mean, how can I get a referenced object with only a subset of keys, but who are connected to the original object?"_ – jabaa May 05 '22 at 16:36
-
@jabaa you are right! But what the OP asked isn't shallow copy – R4ncid May 05 '22 at 16:38
-
@R4ncid - ...and additionally, `JSON.parse(JSON.stringify(x))` is a terrible way to copy something. It's lossy, makes a completely unnecessary round-trip through text, ... If you want a deep copy, [do a deep copy without JSON](https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript). – T.J. Crowder May 05 '22 at 16:38
-
1@R4ncid Yes, the terminology is wrong and confusing. – jabaa May 05 '22 at 16:38
-
Welcome to Stack Overflow! Please take the [tour] if you haven't already (you get a badge!), have a look around, and read through the [help], in particular [*How do I ask a good question?*](/help/how-to-ask) I also recommend Jon Skeet's [Writing the Perfect Question](https://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/) and [Question Checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). – T.J. Crowder May 05 '22 at 16:40
-
I could think of two options. Either use a [proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) or a class containing a reference to the original object as [private property](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields) and [getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get) and [setters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set) to access the properties in the original object. – jabaa May 05 '22 at 16:41
2 Answers
You could use an array containing the props you want, and then hacky nonsense with getters and setters to build an object that actually reads from/writes to a different object.
Note: I've never needed to do this. I think you might have better luck with a different general approach, like "Use the same object, but only display the properties that are appropriate instead of all of them".
let original={ a:1, b:2, c:3};
let propsInNewObject = ["a", "c"];
const reconstructed = propsInNewObject.reduce((obj, el) => {
Object.defineProperty(obj, el, {
get: () => original[el],
set: (value) => { original[el] = value },
enumerable: true
});
return obj;
}, {});
console.log(reconstructed, original);
reconstructed.a = 100;
console.log(reconstructed, original);

- 20,957
- 5
- 26
- 41
-
Fine, anyway I will try a different approach. I only want to send through websockets a subset of the properties of an object that gets updated in realtime. – Luis May 05 '22 at 21:17
This might be the wrong answer because your question is unclear, especially regards which bit is the 'shallow' copy.
Your reconstructed object is a new, independent object, and not connected to the source object in any way.
let reconstructed = { a, b }
// ^ ^
// denotes a new object
The question is, what types might a
and b
, be? If the properties deconstructed from the source object are themselves references (other objects), then modifying the deconstructed value, either in its independent state, or when assigned to the reconstructed object, will change the source value too.
let foo = { a: 1, b: 2 }
let { a, b } = foo
a = 999
console.log(foo, a, b)
let bar = { baz: { msg: 'Hello World' } }
let { baz } = bar
let bar1 = { baz }
baz.msg = 'Hello Sailor'
console.log(bar, baz, bar1)

- 3,133
- 1
- 17
- 24