I'm trying to create a JavaScript class which takes an object as its only argument. The object properties shall be merged with some defaults which are defined in the class itself (and then be used as class fields). So far I'm using object destructuring to achieve what I want to do – which works great when the object is only one level deep. As soon as I use a nested object I'm not able to overwrite "parent" properties (without passing a nested object) anymore.
Is object destructuring even the right approach to what I want to do?
The class itself looks like this
class Class {
constructor( args = {} ) {
this.prop1 = {};
( {
type: this.type = 'default',
prop1: {
value1: this.prop1.value1 = 'one',
value2: this.prop1.value2 = 'two',
value3: this.prop1.value3 = 'three'
} = this.prop1
} = args );
}
}
Expected
When creating a new Class with the following call
new Class( { type: 'myclass', prop1: { value1: 1 } } );
the class fields are assigned properly and the class has the following structure:
{
type: 'myclass',
prop1: {
value1: 1,
value2: 'two',
value3: 'three'
}
}
Which is perfect and exactly what I want to achieve.
Unexpected
It gets tricky when I want to overwrite some fields not with the expected values / structure. A new class creation like the following "fails" as the input values are overwritten with the default values.
The following call
new Class( { type: 'myclass', prop1: 'myProp1' } );
results in the following structure:
{
type: 'myclass',
prop1: {
value1: 'one',
value2: 'two',
value3: 'three'
}
}
Which is not what I want it to be / what I expected. I would have expected the following structure:
{
type: 'myclass',
prop1: 'myProp1'
}
Is there any way to generate the class in the described way – using object destructuring – or is it just not the right use case?
Thanks in advance!
If I was reviewing your code, I would make you change it. I've never seen destructuring used like that to set values on another object. It's very strange and smelly... but I see what you're trying to do.
In the most simple of cases, I suggest using
Object.assignin this scenario. This allows you to merge multiple objects in the way you want (notice how easy it is to read):This will only merge top-level properties. If you want to merge deeply nested objects too, you will need to do that by hand, or use a tool like deepmerge. Here's an example of doing it by hand (while less easy to read, it's still pretty normal code):