and the difference between js and shallow copy implementation of deep copy

How to distinguish between deep and shallow copy copy, simply point, it is assumed that the copy B A, when modifying A, B to see whether the change would happen if B also followed changed, stated that this is a shallow copy, get short of manpower, if B has not changed, and that is a deep copy, self-reliant.

1. If the basic data types, the names and values ​​are saved in the stack memory

var a = 1;
b = a; // 栈内存会开辟一个新的内存空间,此时b和a都是相互独立的 b = 2; console.log(a); // 1 

Of course, this is not really a deep copy, because a deep copy only the data itself for more complex object types.

2. If reference data types, there is the name of the stack memory, heap memory value exists, but the value of the address stack memory will provide a reference point to heap memory

For example, a shallow copy:
 
image.png

When b = a copy, the copy is actually a reference to the address, rather than the value of the stack inside.


 
image.png

When we change the array when a [0] = 1, since the points a and b are the same address, so naturally also influenced by b, which is called a shallow copy.


 
image.png

That, if the heap memory has opened a new memory dedicated to storing b value, just as the basic type, would not you achieve a deep copy of the results
 
image.png

3. The method implemented shallow copy

(1) for ··· in only the first layer loop

// 只复制第一层的浅拷贝
function simpleCopy(obj1) { var obj2 = Array.isArray(obj1) ? [] : {}; for (let i in obj1) { obj2[i] = obj1[i]; } return obj2; } var obj1 = { a: 1, b: 2, c: { d: 3 } } var obj2 = simpleCopy(obj1); obj2.a = 3; obj2.c.d = 4; alert(obj1.a); // 1 alert(obj2.a); // 3 alert(obj1.c.d); // 4 alert(obj2.c.d); // 4 

(2) Object.assign Method

var obj = {
    a: 1, b: 2 } var obj1 = Object.assign({},obj); boj1.a = 3; console.log(obj.a) // 3 

(3) Assignment directly =

let a=[0,1,2,3,4], b=a; console.log(a===b); a[0]=1; console.log(a,b); 
 
image.png

4. Method to achieve deep copy of

(1) to copy all levels using recursive properties

function deepClone(obj){ let objClone = Array.isArray(obj)?[]:{}; if(obj && typeof obj==="object"){ for(key in obj){ if(obj.hasOwnProperty(key)){ //判断ojb子元素是否为对象,如果是,递归复制 if(obj[key]&&typeof obj[key] ==="object"){ objClone[key] = deepClone(obj[key]); }else{ //如果不是,简单复制 objClone[key] = obj[key]; } } } } return objClone; } let a=[1,2,3,4], b=deepClone(a); a[0]=2; console.log(a,b); 

result:


 
image.png

(2) achieved by deep copy JSON object

function deepClone2(obj) { var _obj = JSON.stringify(obj), objClone = JSON.parse(_obj); return objClone; } 

Disadvantages: deep copy object can not be achieved in the method, will appear as undefined
achieve deep copy (3) extend by the method of jQuery

var array = [1,2,3,4]; var newArray = $.extend(true,[],array); // true为深拷贝,false为浅拷贝 

(4) lodash achieve deep copy library

let result = _.cloneDeep(test)

(5) Reflect method

// 代理法
function deepClone(obj) { if (!isObject(obj)) { throw new Error('obj 不是一个对象!') } let isArray = Array.isArray(obj) let cloneObj = isArray ? [...obj] : { ...obj } Reflect.ownKeys(cloneObj).forEach(key => { cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key] }) return cloneObj } 

(6) effected manually deep copy

let obj1 = {
   a: 1, b: 2 } let obj2 = { a: obj1.a, b: obj1.b } obj2.a = 3; alert(obj1.a); // 1 alert(obj2.a); // 3 

(7) If the object is a primitive value, then, may be implemented by Object.assign deep copy, but it should be assigned to an empty object

var obj = {
    a: 1, b: 2 } var obj1 = Object.assign({}, obj); // obj赋值给一个空{} obj1.a = 3; console.log(obj.a);// 1 
 
image.png

(8) to achieve a deep copy of the array slice

// 当数组里面的值是基本数据类型,比如String,Number,Boolean时,属于深拷贝
// 当数组里面的值是引用数据类型,比如Object,Array时,属于浅拷贝
var arr1 = ["1","2","3"]; var arr2 = arr1.slice(0); arr2[1] = "9"; console.log("数组的原始值:" + arr1 ); console.log("数组的新值:" + arr2 ); 
 
image.png

(9) realized with a deep copy of the array concat

// 当数组里面的值是基本数据类型,比如String,Number,Boolean时,属于深拷贝
var arr1 = ["1","2","3"]; var arr2 = arr1.concat(); arr2[1] = "9"; console.log("数组的原始值:" + arr1 ); console.log("数组的新值:" + arr2 ); // 当数组里面的值是引用数据类型,比如Object,Array时,属于浅拷贝 var arr1 = [{a:1},{b:2},{c:3}]; var arr2 = arr1.concat(); arr2[0].a = "9"; console.log("数组的原始值:" + arr1[0].a ); // 数组的原始值:9 console.log("数组的新值:" + arr2[0].a ); // 数组的新值:9 
 
image.png

(10) directly var newObj = Object.create (oldObj), can achieve the effect of a 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; } 

(11) using the extended operator to achieve deep copy

// 当value是基本数据类型,比如String,Number,Boolean时,是可以使用拓展运算符进行深拷贝的
// 当value是引用类型的值,比如Object,Array,引用类型进行深拷贝也只是拷贝了引用地址,所以属于浅拷贝
var car = {brand: "BMW", price: "380000", length: "5米"} var car1 = { ...car, price: "500000" } console.log(car1); // { brand: "BMW", price: "500000", length: "5米" } console.log(car); // { brand: "BMW", price: "380000", length: "5米" }



Guess you like

Origin www.cnblogs.com/yinhao-jack/p/12324922.html