Jason Pacini
Jason Pacini

Reputation: 21

Javascript constructor creating new objects with same values as previously created object

Here is my (simplified) constructor:

class User {
    constructor() {
        Object.assign(this, setup); 
    }
}

const setup = {
    name: ''
}

export { User }

When I create a new object

import {
    User
} from './User.js';

let user1 = new User();

user1 is what I expect.

If I declare user1.name = 'John' and then create another user let user2 = new User() then user2.name will be John, not an empty string.

Can someone explain why?

It appears setup is being changed and referenced instead of the new user object that was created.

Upvotes: 2

Views: 57

Answers (2)

Jason Pacini
Jason Pacini

Reputation: 21

For anyone else running into similar issues, I finally figured it out. It boils down to shallow copying versus deep copying in Javascript. Both spread (...) and Object.assign() perform a shallow copy while JSON methods perform a deep copy.

If your setup is a nested object such as

const setup = {
    name: '',
    address: {
        city: ''
    }
}

the address object inside of setup will remain a referenced value, not a primitive value, when {...} or Object.assign() is used.

If you want to copy the whole object, you need to copy it as JSON.parse(JSON.stringify(setup)) so my constructor should be

class User {
    constructor() {
        Object.assign(this, JSON.parse(JSON.stringify(setup))); 
    }
}

since this performs a deep (nested) copy.

Upvotes: 0

Maheer Ali
Maheer Ali

Reputation: 36584

It appears setup is being changed and referenced instead of the new user object that was created.

Yes. You need to make a copy of object before assigning it to instance of class

class User {
    constructor() {
        Object.assign(this, {...setup}); 
    }
}

Upvotes: 3

Related Questions