1.0.13 • Published 4 years ago
nest-object-deep-copy v1.0.13
Deep Copy Nested Objects
If this project helps you, please support it with a star :heart: (Thank you!).
What
This is pure javascript function that aims to create a real hard copy from original javascript object.
Why
- It is just a pure function and final import size is only 662 bytes.
- It gives you the real hard copy, avoids limitations of using spread operator, Object.assign and JSON.parse(JSON.stringify(object)).
Feature | JSON.parse(JSON.stringify(object)) | spread operator / Object.assign | nest-object-deep-copy |
---|---|---|---|
Hard Copy nested object | :heavy_check_mark: | :x: | :heavy_check_mark: |
Copy functions | :x: | :heavy_check_mark: | :heavy_check_mark: |
Keep prototype chain | :x: | :x: | :heavy_check_mark: |
Circular Reference | Throw Error | Keep Circular Ref | Graceful Handle |
Gracefully handle Circular Reference
const originalObject = {
a: 'test',
f: 1
};
originalObject.a = originalObject;
originalObject.b = {};
originalObject.b.c = originalObject;
deepCopy(originalObject)
will result in:
{
a: '[Circular]',
f: 1,
b: {
c: '[Circular]',
},
};
Limitions of common ways
Cannot make hard copy on nested objects
let user = {
id: 101,
gender: 'male',
personalInfo: {
name: 'Jack',
}
};
Then the spread operator or Object.assign() WILL NOT give you a hard copied object:
let copiedUser = {
...user
};
// Change a nested object value
copiedUser.personalInfo.name = 'Tom';
// Change a property which holds a primitive value
copiedUser.id = 2;
// original user object mutation happens
console.log(user.personalInfo.name); // 'Tom'
console.log(copiedUser.personalInfo.name); // 'Tom'
// BUT mutation does not happen to property which holds a primitive value
console.log(user.id); // 1
console.log(copiedUser.id); // 2
Loosing functions
let user = {
id: 1,
name: 'jack',
speak: function() {
console.log('I am speaking from original object.');
}
};
let copiedUser = JSON.parse(JSON.stringify(user));
user.speak(); // `I am speaking from original object.`
copiedUser.speak(); //Uncaught TypeError: copiedUser.speak is not a function
Loosing prototype chain
// Declare a constructor function
function Foo(who) {
this.me = who;
}
// Now there is a new property called 'identify' which equals to a function in prototype chain of any object being created by calling new Foo
Foo.prototype.identify = function() {
return 'I am ' + this.me;
}
// Create a user object by constructor Foo
const user = new Foo('Jack');
// Create a copy object by using spread operator
const copiedUser1 = {...user};
// Prototype chain is lost !!
copiedUser1.identify(); // Uncaught TypeError: copiedUser1.identify is not a function
// Create a copy object by using Object.assign()
const copiedUser2 = Object.assign({}, user);
// Prototype chain is lost !!
copiedUser2.identify(); // Uncaught TypeError: copiedUser2.identify is not a function
// Create a copy object by using JSON.parse(JSON.stringify(object))
const copiedUser3 = JSON.parse(JSON.stringify(user));
// Prototype chain is lost !!
copiedUser3.identify(); // Uncaught TypeError: copiedUser3.identify is not a function
Install
$ npm install nest-object-deep-copy
How to use it
const deepCopy = require('./nest-object-hard-copy');
//Get a hard copy
let copiedUser = deepCopy(object);
License
This project is licensed under the MIT License