Detailed explanation of JS shallow copy and deep copy (huge details)

Table of contents

1. Detailed pre-knowledge

1. JavaScript data types

2. Understand pass-by-value and pass-by-address

Two, shallow copy

1. Definition and principle of shallow copy

2. The method of implementing shallow copy

3. Deep copy

1. Definition and principle of deep copy

2. Implementation method of deep copy


1. Detailed pre-knowledge

Before learning shallow copy and deep copy, we need to know the pre-knowledge

1. JavaScript data types

JavaScript data types are divided into basic types: Number, String, Boolean, Undefined, Null, Symbol, BigInt

                                          Reference type: object (Object), array (Array), function (Function)

Basic type data is stored in stack memory

The reference type data is stored in the heap memory, and the variable of the reference data type is a reference to the actual object in the heap memory, which is stored in the stack

2. Understand pass-by-value and pass-by-address

Pass by value: open up a new memory area to store values

The code example is as follows

            let a = 3;
            let b = a;
            console.log(a, b);  // 3 3
            b = 5;  
            console.log(a, b);  // 3 5

Addressing: passing memory addresses without opening up new space

            let obj = {
                name: 'zs',
                age: 20,
            };
            let obj1 = obj;
            console.log(obj, obj1);
            obj1.name = 'lisi';
            console.log(obj, obj1);

 

The output is the same, obj and obj1 point to the same memory address.

Two, shallow copy

1. Definition and principle of shallow copy

Shallow copy refers to the creation of new data that has an exact copy of the original data attribute values

If the attribute is a primitive type, the value of the primitive type is copied. If the attribute is a reference type, the memory address is copied

That is, the shallow copy is to copy one layer, and the deep reference type shares the memory address

2. The method of implementing shallow copy

(1). Handwritten recursive implementation

            // 手写实现浅拷贝
            function shallowClone(obj) {
                let newObj = {};
                for (let i in obj) {
                    // 只要是obj的属性,直接复制一份给newObj
                    if (obj.hasOwnProperty(i)) {
                        newObj[i] = obj[i];
                    }
                }
                return newObj;
            }
            const person = {
                name: 'zs',
                hobby: ['排球', '网球', '篮球'],
            };
            const person1 = shallowClone(person);
            console.log(person);
            console.log(person1);
            person1.name = 'lisi';
            person1.hobby[0] = '足球';
            console.log(person);
            console.log(person1);

The printout results are as follows

(2). Use the expansion syntax to realize shallow copy

            let obj = {
                name: 'zs',
                lessons: ['hobby', 'suxexu', 'kligh'],
            };
            let hd1 = { ...obj };
            hd1.name = 'lisi';
            hd1.lessons[0] = 'math';
            console.log(obj);
            console.log(hd1);

 (3).Object.assign merges objects

            let obj = {
                name: 'zs',
                lessons: ['hobby', 'suxexu', 'kligh'],
            };
            let newObj = Object.assign({}, obj);
            newObj.lessons[0] = 'math';
            console.log(obj);
            console.log(newObj);

(4).Using Array.prototype.,slice()

            const arr = [1, 2, { name: 'nordon' }];
            const newArr = arr.slice();
            newArr[2].name = 'wy';
            console.log(arr);
            console.log(newArr);

(5).Using Array.prototype.contact()

            const arr = [1, 2, { name: 'nordon' }];
            const newArr = arr.concat();
            newArr[2].name = 'wy';
            console.log(arr);
            console.log(newArr); 

3. Deep copy

1. Definition and principle of deep copy

  Deep copy creates a new stack. The properties of the two objects are identical, but they correspond to two different addresses. Modifying the properties of one object will not change the properties of the other object.

2. Implementation method of deep copy

(1).Recursive implementation of deep copy

the first method

            function deepClone(obj) {
                let newObj = obj instanceof Array ? [] : {};
                for (let i in obj) {
                    if (obj.hasOwnProperty(i)) {
                        if (obj[i] && typeof obj[i] == 'object') {
                            // 若对象属性还是引用类型,进行递归
                            newObj[i] = deepClone(obj[i]);
                        } else {
                            // 对象属性为基础数据类型,直接赋值
                            newObj[i] = obj[i];
                        }
                    }
                }
                return newObj;
            }
            const obj = {
                name: 'zs',
                hobby: ['排球', '网球', '乒乓球'],
            };
            const newObj = deepClone(obj);
            newObj.name = 'lisi';
            newObj.hobby[0] = '篮球';
            console.log(obj);
            console.log(newObj);

The second method is to use Object.entries(obj) skillfully to traverse the properties and values ​​of objects

            function deepClone(obj) {
                let newObj = obj instanceof Array ? [] : {};
                for (const [k, v] of Object.entries(obj)) {
                    newObj[k] = typeof v == 'object' ? deepClone(v) : v;
                }
                return newObj;
            }
            const obj = {
                name: 'zs',
                hobby: ['排球', '网球', '乒乓球'],
            };
            const newObj = deepClone(obj);
            newObj.name = 'lisi';
            newObj.hobby[0] = '篮球';
            console.log(obj);
            console.log(newObj);

The output is the same, as follows:

(2).JSON.parse(JSON.stringify(object to be copied))

            const obj = {
                name: 'zs',
                hobby: ['排球', '网球', '乒乓球'],
            };
            const newObj = JSON.parse(JSON.stringify(obj));
            newObj.name = 'lisi';
            newObj.hobby[0] = '篮球';
            console.log(obj);
            console.log(newObj);

 (3) The first parameter of $.extend() in .jQuery is set to true for deep copy, and false for shallow copy (to introduce JQuery library)

            const obj1 = {
                a: 1,
                b: { f: { g: 1 } },
                c: [1, 2, 3],
            };
            const obj2 = $.extend(true, {}, obj1);
            console.log(obj1.b.f === obj2.b.f);

(4). Introduce loadsh and provide cloneDeep implementation

Steps to implement deep copy using loash library in Vue

  1. install loadsh npm i --save  lodash
  2. Introduce loadsh import _ from 'lodash'
  3. Directly call the method of loadsh library const newObj = _.cloneDeep(this.obj)

Guess you like

Origin blog.csdn.net/qq_63299825/article/details/131003216