Languages
[Edit]
EN

JavaScript - clone object

4 points
Created by:
Maison-Humphries
791

In this article, we would like to show you how to clone objects in JavaScript.

1. Object.assign method example

This approach makes copies of first-level entries.

// ONLINE-RUNNER:browser;

function cloneObject(object) {
	return Object.assign(new Object(), object);
}


// Example:

var studentObject = {
    name: 'John',
    age: 25,
    todos: [
        'Sleeping', 'Lectures', 'Classes', 'Shopping'
    ],
    action: function() { /* ... */ }
}

var studentObjectCopy = cloneObject(studentObject);

studentObject.age = 30;
studentObject.todos[0] = 'Modiffied Sleeping';

console.log(studentObject.name + ' ' + studentObject.age);
console.log(studentObject.todos);
console.log(studentObject.action);

console.log(studentObjectCopy.name + ' ' + studentObjectCopy.age);
console.log(studentObjectCopy.todos);
console.log(studentObjectCopy.action);

Note: this approach has ben introducd in ECMAScript 2015.

2. Spread syntax example

This approach makes copies of first-level entries.

// ONLINE-RUNNER:browser;

var studentObject = {
    name: 'John',
    age: 25,
    todos: [
        'Sleeping', 'Lectures', 'Classes', 'Shopping'
    ],
    action: function() { /* ... */ }
}

var studentObjectCopy = { ...studentObject };

studentObject.age = 30;
studentObject.todos[0] = 'Modiffied Sleeping';

console.log(studentObject.name + ' ' + studentObject.age);
console.log(studentObject.todos);
console.log(studentObject.action);

console.log(studentObjectCopy.name + ' ' + studentObjectCopy.age);
console.log(studentObjectCopy.todos);
console.log(studentObjectCopy.action);

Note: this approach has been intorduced in ECMAScript 2018.

3. Custom clone function example

Note: read this article to know how to check types in JavaScript. 

// ONLINE-RUNNER:browser;

function getType(object) {
	return Object.prototype.toString.call(object);
}

function cloneArray(array) {
	let result = [ ];
	for (var i = 0; i < array.length; ++i) {
		result.push(cloneEntry(array[i]));
	}
	return result;	
}

function cloneObject(object) {
	let result = new Object();
	for (var property in object) {
		if (object.hasOwnProperty(property)) {
			result[property] = cloneEntry(object[property]);
		}
	}
	return result;	
}

function cloneEntry(entry) {
  	var type = getType(entry);
  
  	switch(type) {
        case '[object Array]':     return cloneArray(entry);
        case '[object Object]':    return cloneObject(entry);
        case '[object Null]':      return null;
        case '[object Undefined]': return undefined;
        case '[object Boolean]':   return Boolean(entry);
        case '[object Number]':    return Number(entry);
        case '[object BigInt]':    return BigInt(entry);
        case '[object String]':    return String(entry);
        case '[object Date]':      return new Date(entry.getTime());
        case '[object Function]':  throw new Error('Function type is not allowed.');
        default:                   throw new Error(type + ' copy operation is not supported.');
	}
}


// Example:

var studentObject = {
    name: 'John',
    age: 25,
    todos: [
        'Sleeping', 'Lectures', 'Classes', 'Shopping'
    ]
}

var studentObjectCopy = cloneEntry(studentObject);

console.log(studentObject.name + ' ' + studentObject.age 
            + ' ' + studentObject.todos);

console.log(studentObjectCopy.name + ' ' + studentObjectCopy.age 
            + ' ' + studentObjectCopy.todos);

4. Converting to JSON and back example

This approach makes deep cloning avoiding functions and added entries (properties or methods) to objects e.g. additional properties inside Array type object - some entries are still not copied.

// ONLINE-RUNNER:browser;

function cloneObject(object) {
  	var json = JSON.stringify(object);
  
	return JSON.parse(json);
}


// Example:

var studentObject = {
    name: 'John',
    age: 25,
    todos: [
        'Sleeping', 'Lectures', 'Classes', 'Shopping'
    ],
    action: function() { /* ... */ }
}


var studentObjectCopy = cloneObject(studentObject);

studentObject.todos.property = 'This is property value';

console.log(studentObject.name + ' ' + studentObject.age);
console.log(studentObject.todos);

console.log(studentObjectCopy.name + ' ' + studentObjectCopy.age);
console.log(studentObjectCopy.todos);

console.log(studentObject.action + '  vs  ' + studentObjectCopy.action);
console.log(studentObject.todos.property + '  vs  ' + studentObjectCopy.todos.property);

5. Custom clone function vs clone with converting to JSON performance

// ONLINE-RUNNER:browser;

var count = 100000;

var studentObject = {
    name: 'John',
    age: 25,
    todos: [
        'Sleeping', 'Lectures', 'Classes', 'Shopping'
    ]
}

// Test 1: clone with converting to json

;(function() {
    function cloneObject(object) {
        var json = JSON.stringify(object);

        return JSON.parse(json);
    }
  
    var t1 = new Date();

    for(var i = 0; i < count; ++i) {
        var studentObjectCopy = cloneObject(studentObject);
    }

    var t2 = new Date();
    var dt = t2 - t1;

    console.log(dt + 'ms <- clone with converting to json');
})();

// Test 2: custom deep clone

;(function() {
    function getType(object) {
        return Object.prototype.toString.call(object);
    }

    function cloneArray(array) {
        let result = [ ];
        for (var i = 0; i < array.length; ++i) {
            result.push(cloneEntry(array[i]));
        }
        return result;	
    }

    function cloneObject(object) {
        let result = new Object();
        for (var property in object) {
            if (object.hasOwnProperty(property)) {
                result[property] = cloneEntry(object[property]);
            }
        }
        return result;	
    }

    function cloneEntry(entry) {
        var type = getType(entry);

        switch(type) {
            case '[object Array]':     return cloneArray(entry);
            case '[object Object]':    return cloneObject(entry);
            case '[object Null]':      return null;
            case '[object Undefined]': return undefined;
            case '[object Boolean]':   return Boolean(entry);
            case '[object Number]':    return Number(entry);
            case '[object BigInt]':    return BigInt(entry);
            case '[object String]':    return String(entry);
            case '[object Date]':      return Date(entry);
            case '[object Function]':  throw new Error('Function type is not allowed.');
            default:                   throw new Error(type + ' copy operation is not supported.');
        }
    }

	var t1 = new Date();

    for(var i = 0; i < count; ++i) {
        var studentObjectCopy = cloneEntry(studentObject);
    }

    var t2 = new Date();
    var dt = t2 - t1;

    console.log(dt + 'ms <- custom deep clone');
})();

Alternative titles

  1. JavaScript - how to copy object?
  2. JavaScript - how to make copy of object?
  3. JavaScript - how to duplicate object?
  4. JavaScript - how to clone object?
Donate to Dirask
Our content is created by volunteers - like Wikipedia. If you think, the things we do are good, donate us. Thanks!
Join to our subscribers to be up to date with content, news and offers.
Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join