How can I modify a class instance using the spread operator, while keeping its constructor the same?
The question may be clearer with an example.
class User {
constructor({ name = "", age = 0 }) {
this.name = name
this.age = age
}
getName() {
return this.name
}
getAge() {
return this.age
}
}
Creating a regular instance works fine:
const u1 = new User({ name: 'John Doe', age: 33 })
console.log(u1.getAge()) // 33
What does not work is using the spread operator with the instance:
const u2 = { ...u1, age: 34 }
console.log(u2.getAge()) //
I read that the spread operator only copies own enumerable properties, so I also tried this:
const u3 = { ...u1, ...User.prototype, age: 34 }
console.log(u3.getAge())
This works better (it allows me to call the methods in User
), but still breaks when using instanceof
or Object.isPrototypeOf()
:
console.log(u1 instanceof User) // true
console.log(u2 instanceof User) // false
console.log(u3 instanceof User) // false
console.log(User.isPrototypeOf(u1)) // true
console.log(User.isPrototypeOf(u2)) // false
console.log(User.isPrototypeOf(u3)) // false
I also tried these, but they didn't work either:
const u4 = Object.assign({ age: 34 }, u1)
const u5 = Object.assign({ age: 34 }, u1, User.prototype)
So, TL:DR, is it possible to create a copy of a class instance which changes some properties of the parent, but keeps a reference to its constructor?
Hope I made myself clear. Thanks in advance for the help!
With the { }
object literal notation you always create a plain object, never an instance of your custom class. You should use the new
operator to get a new instance (or Object.create
):
class User {
constructor({ name = "", age = 0 }) {
this.name = name
this.age = age
}
getName() {
return this.name
}
getAge() {
return this.age
}
}
const u1 = new User({ name: 'John Doe', age: 33 })
console.log(u1.getName(), u1.getAge()) // John Doe, 33
const u2 = new User({ ...u1, age: 34 });
console.log(u2.getName(), u2.getAge()) // John Doe, 34
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With