ryandlf
ryandlf

Reputation: 28555

Duplicate/Clone Javascript Object

Is there a way to clone a javascript object? Not a DOM element, but an object with a specific constructor. For instance lets say I have a phone number object:

function PhoneNumber(number, type) {
    this.number = number;
    this.type = type;
}

var phoneObj1 = new PhoneNumber('1111111111', 'Home');
var phoneObj2 = //Copy of phoneObj1, but unique so I can set other parameters if necessary.

jQuery solves this problem for me with extend.

var phoneObj2 = $.extend({}, phoneObj1);

But it returns a generic object:

Object{number:'1111111111' type:'Home'}

Instead of with the Phone Number constructor name. I need a way of passing in the original phoneObj1's constructor without actually writing new PhoneNumber() in the extend, because the code this is being used in is used by many different types of Objects so at any given time I don't know the exact constructor that should be used except for the fact that I have an object to reference.

var phoneObj2 = $.extend(new PhoneNumber(), phoneObj1); //I CANNOT do this!

//Maybe something like this?
var phoneObj2 = $.extend(new phoneObj1.constructor.name, phoneObj1); //This throws an error.

Upvotes: 2

Views: 1988

Answers (4)

am232
am232

Reputation: 1

Checkout the full post -> https://jscurious.com/how-to-deep-clone-objects-in-javascript/

const obj = {
      name: 'Amitav', 
      age: 24,
      address: {
          city: 'Bangalore',
          state: 'Karnataka'
      }
};
 
const makeDeepClone = (obj) => {
    let newObject = {};
 
    Object.keys(obj).map(key => {
        if(typeof obj[key] === 'object'){
            newObject[key] = makeDeepClone(obj[key]);
        } else {
            newObject[key] = obj[key];
        }
  });
 
  return newObject;
}
 
const copyObj = makeDeepClone(obj);
console.log(copyObj); 
// {name: "Amitav", age: 24, address: {city: "Bangalore", state: "Karnataka"}}
copyObj.address.state = 'Odisha';
console.log(obj.address.state); // "Karnataka"
console.log(copyObj.address.state); // "Odisha"

Upvotes: -1

Eric
Eric

Reputation: 6352

I you only need to support modern version of (45) or (34) you can use the new Object.assign() method.

The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.

Example

var phoneObj2 = Object.assign({}, phoneObj1);
console.log(phoneObj2);

This will take all of the properties in phoneObj1, copy them to the empty object {}, and return the combined object as phoneObj2. The empty {} object and the phoneObj2 variable point to the same object in memory after using the assign method.

For more information checkout the info on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

Upvotes: 1

ryandlf
ryandlf

Reputation: 28555

Turns out that

var phoneObj2 = $.extend(new phoneObj1.constructor, phoneObj1);

Does work. I was just cancelling the constructor of phoneObj1 on an unrelated note. So this can be used as an abstract way of cloning an object without specifically writing the actual constructor. I can simply inherit the constructor from the object I am cloning.

Upvotes: 0

jfriend00
jfriend00

Reputation: 708146

You could have a method (perhaps called copy()) on each of your different types of objects that either returns the constructor for that type of object or just makes a copy of itself (calling the right constructor, since it knows what kind of object it is). So, you just call the same method on all the objects and it does the work for you.

You could put this functionality in a base class and all each derived class would have to do is set the constructor function and all the rest of the code would be common.

Upvotes: 1

Related Questions