Top community members
All Wiki Articles Create Wiki Article

Welcome to Dirask IT community! ❤ 💻
We are community of people that helps each other.

If you are beginner in IT field, you are more then welcome to ask questions, it will help you to learn faster. We are here to help you.

We are always beginner in something, we just need to remember it along the way.

there are no wrong questions - Ask Question

JavaScript - how to clone object?

0 contributions
4 points

In JavaScript there are available few ways to clone object. In this article simple solutions how to do it has been presented.

1. Object.assign method example

This approach makes copy 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 copy 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 coppied.

// 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');
})();

 

0 contributions

Checkout latest Findings & News:

Checkout latest questions:

Checkout latest wiki articles:

Hey 👋
Would you like to know what we do?
  • Dirask is IT community, where we share coding knowledge and help each other to solve coding problems.
  • We welcome everyone,
    no matter what the experience,
    no matter how basic the question is,
    this community will help you.
Read more