Kirk Ouimet
Kirk Ouimet

Reputation: 28344

Clone an instantiated object with JavaScript?

Couldn't find an answer dealing with cloning instantiated objects in JavaScript. What's the best way to clone an existing instantiated object? E.g.,

function Person() {
}

Person.prototype.setName = function(name) {
    this.name = name;
}

var person = new Person();
person.setName('Charles Xavier');

function cloneInstantiated(instantiatedObject) {
    var clone = ... new Person ... ????

    return clone;
}

var clone = cloneInstantiated(person);

console.log(clone.name); // Charles Xavier

if(clone !== person) {
    console.log('Success! We have cloned Charles Xavier into a different memory address.');
}

Upvotes: 0

Views: 654

Answers (2)

Tomáš Zato
Tomáš Zato

Reputation: 53119

There's no native or universal way as far as I know. I prefer to write .clone method for my pseudo classes and use it:

Person.prototype.clone = function() {
    var clone = new Person()
    clone.name = this.name;
}

You could loop through own properties of the object to clone them while not copying stuff inherited from other objects:

for(var i in this) {
   if(this.hasOwnProperty(i)) {
       clone[i] = this[i];
   }
}

This will copy everything that was added to your object after instantiating (eg. won't copy the prototype properties which were already added by calling new Person.

Object.getPrototypeOf

thanks to Bergi
This method allows you to retrieve the prototype of any object. So instead of new Name you can use:

var clone = Object.create(Object.getPrototypeOf(this))

That's an universal solution which can save you lot of work. You must then proceed with copying own properties using for(var i in ...).

Object.create (supported since node V8) (MDN)

Finally, you could create a person that inherits from the original object:

var clone = Object.create(this);

That can be useful in special cases, but normally I wouldn't recommend it.

.toSource (Node.js module) (MDN)

It's also interesting to know that you can (in certain browsers firefox only) override method .toSource which is defined for all objects, even the native ones:

toSource method

In certain cases, you might want to do:

Person.prototype.toSource = function() {
    //Assuming name can be given in constructor
    return "new Person("+this.name.toSource()+")";
}

Further reading

Aside from the linked docs, I found this nice article about javascript object inheritance:

Upvotes: 2

Ruchir Gupta
Ruchir Gupta

Reputation: 1000

This works perfectly... Fiddle

function Person() {
}

Person.prototype.setName = function(name) {
    this.name = name;
}

var person = new Person();
person.setName('Charles Xavier');

function cloneInstantiated(instantiatedObject) {
    var clone = {};
    for (key in instantiatedObject) {
        clone[key] = instantiatedObject[key];
    }
    return clone;
}

var clone = cloneInstantiated(person);

console.log(clone.name); // Charles Xavier

if(clone !== person) {
    console.log('Success! We have cloned Charles Xavier into a different memory address.');
}

Upvotes: 0

Related Questions