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