Copy Objects in JavaScript

There are a few different ways you can copy an object in JavaScript and they will behave different. You can find various functions below that takes a object as an argument and returns a copy. I have then written log messages to show the output of: the constructor,instanceof,getProtoTypeof,calling a function from the copied object and calling a property. As you will see all of the different ways have its consequences.

function SimplePerson(name, age) {
  this.name = name;
  this.age = age;
}
SimplePerson.prototype.talk = function(greet) {
  greet = greet || "Hi";
  console.log(greet + " I, " + this.name + ", am " + this.age + " years.");
};

function shallowCopy(oldObj) {
    var newObj = {};
    for(var i in oldObj) {
        if(oldObj.hasOwnProperty(i)) {
            newObj[i] = oldObj[i];
        }
    }
    return newObj;
}
function shallowCopyVar(orginal) {
    // First create an empty object with
    // same prototype of our original source
    var clone = Object.create(Object.getPrototypeOf(orginal)) ;
 
    var i, keys = Object.getOwnPropertyNames(orginal) ;
    for (i = 0 ; i < keys.length ; i += 1)
    {
        // copy each property into the clone
        Object.defineProperty(clone, keys[ i ],
            Object.getOwnPropertyDescriptor(orginal, keys[ i ])
        ) ;
    }
    return clone ;
}

function deepCopy(oldObj) {
    var newObj = oldObj;
    if (oldObj && typeof oldObj === 'object') {
        newObj = Object.prototype.toString.call(oldObj) === "[object Array]" ? [] : {};
        for (var i in oldObj) {
            newObj[i] = deepCopy(oldObj[i]);
        }
    }
    return newObj;
}

function mixedCopy() {
    var i, j, newObj = {};
    for(i = 0; i < arguments.length; i++) {
        for(j in arguments[i]) {
            if(arguments[i].hasOwnProperty(j)) {
                newObj[j] = arguments[i][j];
            }
        }
    }
    return newObj;
}

var simplePerson = new SimplePerson("Jen", 26);
var simplePerson2 = new SimplePerson("Joe", 23);
console.log(simplePerson2.constructor);// Function SimplePerson
console.log(simplePerson2 instanceof SimplePerson);// true
console.log(Object.getPrototypeOf(simplePerson2));
// [object Object]  {talk: function (greet) { greet = greet || "Hi"; window.runnerWindow.proxyConsole.log(greet + " I, " + this.name + ", am " + this.age + " years.");}}
simplePerson2.talk();//"Hi I, Joe, am 23 years."

//ShallowCopy
console.log("My shallow copy");
var anotherPerson = shallowCopy(simplePerson);
console.log(anotherPerson.name); // "Jen"

//commented out as the error breaks the code!
//anotherPerson.talk();//"error" anotherPerson.talk is not a function 
console.log(anotherPerson.constructor); //Function Object [native code]
console.log(anotherPerson instanceof SimplePerson); //false
console.log(Object.getPrototypeOf(anotherPerson));// object Object{ ... }

//shallowCopyVar
console.log("My shallow copy variation");
var anotherShallowPerson = shallowCopyVar(simplePerson);
console.log(anotherShallowPerson.name); // "Jen"
anotherShallowPerson.talk();// "Hi I, Jen, am 26 years."
console.log(anotherShallowPerson.constructor); //Function SimplePerson
console.log(anotherShallowPerson instanceof SimplePerson); //true
console.log(Object.getPrototypeOf(anotherShallowPerson));
// [object Object]  {talk: function (greet) { greet = greet || "Hi"; window.runnerWindow.proxyConsole.log(greet + " I, " + this.name + ", am " + this.age + " years.");}}

//deepCopy
console.log("My deep copy variation");
var anotherDeepPerson = deepCopy(simplePerson);
console.log(anotherDeepPerson.name); // "Jen"
anotherDeepPerson.talk();// "Hi I, Jen, am 26 years."
console.log(anotherDeepPerson.constructor); //Function Object [native code]
console.log(anotherDeepPerson instanceof SimplePerson); //false
console.log(Object.getPrototypeOf(anotherDeepPerson)); //object Object{ ... }

//mixed copy
console.log("My mixed variation");
var anotherMixedPerson = mixedCopy(simplePerson);
console.log(anotherMixedPerson.name); // "Jen"

//commented out as the error breaks the code!
//anotherMixedPerson.talk();// "error" anotherMixedPerson.talk is not a function
console.log(anotherMixedPerson.constructor); //Function Object [native code]
console.log(anotherMixedPerson instanceof SimplePerson); //false
console.log(Object.getPrototypeOf(anotherMixedPerson)); //object Object{ ... }

Add your comment