blindmikey
blindmikey

Reputation: 137

ES6 How to ensure updated clone properties doesn't effect original?

I must be doing something wrong.

  1. Instantiate Person class as Bob with name 'Bob'
  2. Clone Bob as new var Alice
  3. Rename Alice with name 'Alice'
  4. Log names of Bob & Alice

I expect Bob's name will remain 'Bob', but it has updated to 'Alice', despite not updating Bob...?

class Person {
  constructor(attr) {
    this.attr = attr;
  }

  talk() {
    console.log('My name is ' + this.attr.name);
  }
}

function clone(obj) {
  return Object.assign(Object.create(Object.getPrototypeOf(obj)), obj);
}

var Bob = new Person({
  name: 'Bob'
});

var Alice = clone(Bob);
Alice.attr.name = 'Alice';

Alice.talk();
Bob.talk();

Thanks in advance.

Upvotes: 0

Views: 35

Answers (2)

Rajat Badjatya
Rajat Badjatya

Reputation: 818

The simplest solution for cloning is:

var cloned = JSON.parse(JSON.stringify(objectToClone));

But there is a catch in this solution, this will fail when your object's attribute value is a function.

var a = {name: 'a', exec: function() {return true;}};
var b = JSON.parse(JSON.stringify(a));
console.log(b); // {name: 'a'}

for better insight on cloning, you can refer this article: deep cloning

Upvotes: 1

trincot
trincot

Reputation: 350310

Object.assign performs a shallow copy, so Bob and Alice will have their own copy of the attr reference, but they refer to the same nested object. attr.name is still a shared string.

You need to perform a deep(er) copy, or else reassign the attr property:

Alice.attr = { name: 'Alice' };

Upvotes: 2

Related Questions