Some of the problems

// Set 1 let obj1 = {a: 1, b: 2} let obj2 = obj1 obj2.a = 3 console.log(obj1) //? console.log(obj2) // ?Copy the code
C: {q: 6}} let obj2 = obj1 obj2.a = 3 obj2.c.q = 7 console.log(obj1) //? console.log(obj2) // ?Copy the code
Assign ({}, obj1) obj2.a = 3 console.log(obj1) //? console.log(obj2) // ?Copy the code
Let obj1 = {a: 1, b: 2, c: {q: 6 } } let obj2 = Object.assign({}, obj1) obj2.a = 3 obj2.c.q = 7 console.log(obj1) // ? console.log(obj2) // ?Copy the code
// let _ = require('lodash'); let obj1 = { a: 1, b: 2, c: { q: 6 } }; let obj2 = _.cloneDeep(obj1); obj2.a = 3 obj2.c.q = 7 console.log(obj1) // ? console.log(obj2) // ?Copy the code

JS data types and related concepts

The data type

JS has two types of data: basic and reference. Basic type: String Number Boolean Undefined null symbol Reference type: Object Array Function Date

Storage of data in memory

When a variable is defined in JS, the variable is stored in the stack, but there is a difference between the basic type and the reference type. Reference types are stored in heap memory, and Pointers to data (memory addresses) are stored in the stack. That is, when a new variable is defined to copy data, the base type copies the original data, but the reference type does not.

Because of this problem, novices often encounter the problem of copying an object (reference type), making changes to the new object, and then using the original object to find that the original object has also changed. The solution to this problem is to learn the use scenarios for assignment, shallow copy, and deep copy, and flexibly handle reference types for each scenario.

Object assignment, shallow copy, deep copy

Assignment does not create a new object; it simply copies a pointer to the original object. Shallow copy creates a new object that copies only the properties of the original object. If the property value is a primitive type, the original data is copied; if the property value is a reference type, the pointer is copied. Therefore, if an attribute of the original object has reference-type data, either the new object or the reference-type data of the original object will be changed by the other. Deep copy also creates a new object, but not only copies the properties of the original object, but also creates a new address in the heap memory to store the new object, so the new object is not associated with the original object, and modification of one object does not change the other.

Problem solving

// Set 1 to 1 let obj1 = {a: 1, b: 2} let obj2 = obj1 obj2.a = 3 console.log(obj1) // {a: 3, b: 2} console.log(obj2) // {a: 3, b: 2} console.log(obj2) // {a: 3, b: 2} console.log(obj2) // {a: 3, b: 2} console.log(obj2) 3, b: 2}Copy the code
// assign 2 let obj1 = {a: 1, b: 2, c: {q: 6}} let obj2 = obj1 obj2.a = 3 obj2.c.q = 7 console.log(obj1) // {a: 3, b: 2, c: {q: 7}} console.log(obj2) // {a: 3, b: 2, c: {q: 7}}Copy the code
// let obj1 = {a: 1, b: 2} let obj2 = object.assign ({}, obj1) obj2.a = 3 console.log(obj1) // {a: 1, b: 2} let obj2 = object.assign ({}, obj1) obj2 = 3 console.log(obj1) 2} console.log(obj2) // {a: 3, b: 2}Copy the code
Let obj1 = {a: 1, b: 2, c: {q: 6 } } let obj2 = Object.assign({}, obj1) obj2.a = 3 obj2.c.q = 7 console.log(obj1) // {a: 1, b: 2, c: {q: 7}} console.log(obj2) // {a: 3, b: 2, c: {q: 7}}Copy the code
// let _ = require('lodash'); let obj1 = { a: 1, b: 2, c: { q: 6 } }; let obj2 = _.cloneDeep(obj1); obj2.a = 3 obj2.c.q = 7 console.log(obj1) // {a: 1, b: 2, c: {q: 6}} console.log(obj2) // {a: 3, b: 2, c: {q: 7}}Copy the code

Usage scenarios

The original object is used only once (it can be modified without side effects), and assignment is used.

The original object needs to be used multiple times (modification will lead to inaccurate data for subsequent use), and the property has only basic type, no reference type, and shallow copy is used.

If the original data needs to be used multiple times (modification may lead to inaccurate subsequent use data), and the attributes contain reference types, use deep copy.

Shallow copy implementation

Object.assign()

In the example above, object.assign () is a shallow copy

concat

Es5 shallow copy method

Extended operator

Es6 shallow copy method

slice

JS array method

let arr1 = [1, 2, { username: 'Kobe' }];
let arr2 = arr.slice();
arr2[2].username = 'Wade'

console.log(arr1[2]); // { username: 'Kobe' }
console.log(arr2[2]); // { username: 'Wade' }
Copy the code

Lodash clone ()

let _ = require('lodash');
let obj1 = {
    a: 1,
    b: 2,
};

var obj2 = _.clone(obj1);
Copy the code

Handwritten implementation

function shallowClone(source) { var target = {}; for(var i in source) { if (source.hasOwnProperty(i)) { target[i] = source[i]; } } return target; } let obj1 = {... } let obj2 = shallowClone(obj1)Copy the code

Deep copy implementation

JSON.parse(JSON.stringfy())

let obj1 = {a: 1, b: 2}
let obj2 = JSON.parse(JSON.stringify(obj1))
Copy the code

** Caution: Use with caution, because such a deep copy will lose methods if the object has them. * * such as:

Parse (json.stringify (obj1)) console.log(obj1);}} let obj2 = json.parse (json.stringify (obj1)) console.log(obj1); // {a: 1, b: 2, c: ƒ} console.log(obj2); // {a: 1, b: 2}Copy the code

Lodash deepClone ()

let _ = require('lodash');
let obj1 = {
    a: 1,
    b: 2,
    c: {
    	q: 6
    }
};
let obj2 = _.cloneDeep(obj1);
Copy the code

jquery.extend()

$.extend(deepCopy, target, object1, [objectN]) // Let $= require('jquery'); let obj1 = { a: 1, b: 2, c: {q: 6} }; let obj2 = $.extend(true, {}, obj1);Copy the code

Handwritten implementation

Deep copy works by recursively iterating through objects until there are only basic types.

Click to read the handwritten deep copy code