Home > Article > Web Front-end > What are js deep copy and shallow copy and how to implement them
Today I will tell you about the deep copy and shallow copy of JS. What is the difference between them and what are their functions? Let me give you an example below.
var m = { a: 10, b: 20 }var n = m;n.a = 15;//What is the value of m.a at this time?
m.a will output 15, Because this is a shallow copy, n and m point to the same heap, object copy is just a reference of the copied object.
Deep copy
Deep copy is different from the above shallow copy, which is to completely copy an object instead of copying the reference of the object. For example, in the previous example, we write like this:
var m = { a: 10, b: 20 }var n = {a:m.a,b:m.b};n.a = 15;
This time, we output m.a again and find that m.a The value is still 10 and has not changed. Although all the values of the m object and the n object are the same, they are not the same in the heap. This is a deep copy.
Deep copy and shallow copy
The schematic diagram of deep copy and shallow copy is roughly as follows:
Shallow copy only copies points to a certain object pointer without copying the object itself, the old and new objects still share the same memory. However, a deep copy will create an identical object. The new object does not share memory with the original object, and modifications to the new object will not change the original object.
How to implement shallow copy
1. It can be implemented through simple assignment
Similar to the above example, of course, we can also encapsulate a simple function, as follows:
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);
2, Object.assign() implements the
Object.assign() method to copy any number of source object’s own enumerable properties to the target object , and then returns the target object. However, Object.assign() performs a shallow copy, copying references to the object's properties rather than the object itself.
var obj = { a: {a: "hello", b: 21} };var initalObj = Object.assign({}, obj); initalObj.a.a = "changed";console.log( obj.a.a); // "changed"
Note: When the object has only one layer, it is a deep copy, for example, as follows:
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 }
How to implement deep copy
1. Method 1 is still manual copying
Same as the above example, manual copying can achieve deep copy.
2. If the object has only one layer, you can use the above: Object.assign() function
3. Convert to JSON and then back again
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);// falseconsole.log(obj1.body === obj2.body);// false
Use JSON.stringify to Convert the object into a string, and then use JSON.parse to convert the string into a new object.
You can encapsulate the following functions
var cloneObj = function(obj){ var str, newobj = obj.constructor === Array ? [] : {}; if(typeof obj !== 'object'){ return; } else if(window.JSON){ str = JSON.stringify(obj), //系列化对象 newobj = JSON.parse(str); //还原 } else { for(var i in obj){ newobj[i] = typeof obj[i] === 'object' ? cloneObj(obj[i]) : obj[i]; } } return newobj;};
4. Recursive copy
function deepClone(initalObj, finalObj) { var obj = finalObj || {}; for (var i in initalObj) { var prop = initalObj[i]; // 避免相互引用对象导致死循环,如initalObj.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);console.log(str.a);
5. Use the Object.create() method
Use var newObj = Object directly. create(oldObj) can achieve the effect of deep copy.
function deepClone(initalObj, finalObj) { var obj = finalObj || {}; for (var i in initalObj) { var prop = initalObj[i]; // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况 if(prop === obj) { continue; } if (typeof prop === 'object') { obj[i] = (prop.constructor === Array) ? [] : Object.create(prop); } else { obj[i] = prop; } } return obj;}
6, jquery
jquery provides a $.extend that can be used for 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
7, lodash
Another very popular function library, lodash, also provides _.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
This performance is not bad and it is very simple to use.
I believe you have mastered the methods after reading these cases. For more exciting information, please pay attention to other related articles on the php Chinese website!
Related reading:
How to deal with the incomplete display of the last line of text in HTML
How to use css3 to create icon effects
The above is the detailed content of What are js deep copy and shallow copy and how to implement them. For more information, please follow other related articles on the PHP Chinese website!