Shallow copy
It refers to the same block of memory, so if you change any value in it, the other value will change, which is a shallow copy.
var m = { a: 10, b: 20 }; var n = m; n.a = 13; console.log(m.a); // 13 n and m refer to the same heap. Object replication is just a reference to the copied object.Copy the code
Deep copy
var n = { a: m.a, b: m.b }; n.a = 13; console.log(m.a); / / 10Copy the code
M objects and N objects all have the same value, but in the heap, the corresponding is not the same, this is a deep copy. Deep copy is different from shallow copy in that it copies an object completely, not a reference to the object.
The difference between deep copy and shallow copy
Shallow copy copies only Pointers to an object, not the object itself, and the old and new objects still share the same memory. But deep copy will create another identical object, the new object and the original object do not share memory, modify the new object will not change to the original object.
Shallow Cubby thinks of the relationship between you and your shadow: when you die, your shadow dies
Deep copy is like your clone, you die, but your clone lives
Shallow copy implementation
Shallow copy :1. This can be achieved by simple assignment
function simpleClone(initalObj) {
var obj = {};
for ( var i in initalObj) {
obj[i] = initalObj[i];
}
return obj;
}
var obj = {
a: "hello",
b:{
a: "world",
b: 21
},
c:["Bob", "Tom", "Jenny"],
d:function() {
alert("hello world");
}
}
var cloneObj = simpleClone(obj);
console.log(cloneObj.b);
console.log(cloneObj.c);
console.log(cloneObj.d);
cloneObj.b.a = "changed";
cloneObj.c = [1, 2, 3];
cloneObj.d = function() { alert("changed"); };
console.log(obj.b);
console.log(obj.c);
console.log(obj.d);
Copy the code
Shallow copy :2. object.assign () implementation
Object.assign() copies only the attribute value. If the source Object’s attribute value is a reference to the Object, it copies only that reference value. So object.assign () can only be used for shallow copy or merge objects. This is where object.assign () is worth noting.
var obj = { a: {a: "hello", b: 21} };
var initalObj = Object.assign({}, obj);
initalObj.a.a = "changed";
console.log(obj.a.a); // changed
Copy the code
But when the object has only one layer, it is a deep copy
var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = Object.assign({}, obj1);
obj2.b = 100;
console.log(obj1); // {a: 10, b: 20, c: 30}
console.log(obj2); // {a: 10, b: 100, c: 30}
Copy the code
Deep copy implementation
Deep copy :1. Simple assignment
var m = { a: 10, b: 20 }
var n = {a:m.a,b:m.b};
n.a = 15;
console.log(m); // {a: 10, b: 20}
console.log(n); // {a: 15, b: 20}
Copy the code
Note: m object and n object although all values are the same, but in the heap, the corresponding is not the same. This is the deep copy.
2. If the Object has only one layer, you can use object.assign ().
Parse () and json.stringify ()
Json.parse () and json.stringify () only handle data structures that can be represented by JSON, such as Number, String, Array, etc., so functions that cannot be represented by JSON will not be handled correctly.
var obj1 = { body: { a: 10 } };
var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.body.a = 20;
console.log(obj1); // { body: { a: 10 } };
console.log(obj2); // { body: { a: 20 } };
console.log(obj1 === obj2); // false
console.log(obj1.body === obj2.body); // false
Copy the code
Convert the object to a string using json.stringify, and convert it to an object using json.parse. Encapsulate as a function:
var cloneObj = function (obj) { var str, newObj = obj.constructor === Array ? [] : {}; if (typeof obj ! == 'object') return ; if (window.JSON) { str = JSON.stringify(obj); // Serialize the object newObj = json.parse (STR); Else {for (var I in obj) {newObj[I] = typeof obj[I] === 'object'? cloneObj(obj[i]):obj[i]; } } return newObj; };Copy the code
Deep copy :4. Recursive copy
function deepClone(initalObj, finalObj) { var obj = finalObj || {}; for (var i in initalObj) { var prop = initalObj[i]; A = initalObj if(prop === obj) {continue; } if (typeof prop === 'object') { obj[i] = (prop.constructor === Array) ? [] : {}; arguments.callee(prop, obj[i]); } else {obj[I] = prop; } } return obj; } var str = {}; var obj = { a: {a: "hello", b: 21} }; deepClone(obj, str); obj.a = {m:1,n:{a:1,b:2}} console.log(obj); // {m:1,n:{a:1,b:2}} console.log(str); // { a: {a: "hello", b: 21} }Copy the code
Deep copy :5. object.create () : Use object.create () to achieve the effect of deep copy
The object.create () method creates a new Object, using an existing Object to provide the __proto__ of the newly created Object
function deepClone(initalObj, finalObj) { var obj = finalObj || {}; for (var i in initalObj) { var prop = initalObj[i]; A = initalObj if(prop === obj) {continue; } if (typeof prop === 'object') { obj[i] = (prop.constructor === Array) ? [] : Object.create(prop); console.log('Object.create(prop):', Object.create(prop)); The object.create () method creates a new Object, using an existing Object to provide the newly created Object's __proto__} else {obj[I] = prop; } } return obj; } var str = {}; var obj = { a: {a: "hello", b: 21} }; deepClone(obj, str); console.log(obj); // { a: {a: "hello", b: 21} } console.log(str.a.a); // helloCopy the code
6. JQeury extend() method
Extend ([deep], target, object1 [, objectN]), where deep is Boolean, if true, deep copy.
var $ = require('jquery');
var obj1 = {
a: 1,
b: { f: { g: 1 } },
c: [1, 2, 3]
};
var obj2 = $.extend(true, {}, obj1);
console.log(obj1.b.f === obj2.b.f); // false
Copy the code
7. Lodash: Popular libraries provide _. CloneDeep for Deep Copy
var _ = require('lodash');
var obj1 = {
a: 1,
b: { f: { g: 1 } },
c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f); // false
Copy the code
Good performance and easy to use