Explicación detallada de la copia superficial y la copia profunda de JS (enormes detalles)

Tabla de contenido

1. Conocimiento previo detallado

1. Tipos de datos de JavaScript

2. Comprender la transferencia por valor y la transferencia por dirección

Dos, copia superficial

1. Definición y principio de copia superficial

2. El método de implementación de copia superficial

3. Copia profunda

1. Definición y principio de copia profunda

2. Método de implementación de copia profunda


1. Conocimiento previo detallado

Antes de aprender copia superficial y copia profunda, necesitamos conocer el conocimiento previo

1. Tipos de datos de JavaScript

Los tipos de datos de JavaScript se dividen en tipos básicos: Número, Cadena, Booleano, Indefinido, Nulo, Símbolo, BigInt

                                          Tipo de referencia: objeto (Objeto), matriz (Array), función (Función)

Los datos de tipo básico se almacenan en la memoria de pila

Los datos del tipo de referencia se almacenan en la memoria del montón, y la variable del tipo de datos de referencia es una referencia al objeto real en la memoria del montón, que se almacena en la pila.

2. Comprender la transferencia por valor y la transferencia por dirección

Pasar por valor: abre una nueva área de memoria para almacenar valores

El ejemplo de código es el siguiente

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

Direccionamiento: paso de direcciones de memoria sin abrir nuevo espacio

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

 

La salida es la misma, obj y obj1 apuntan a la misma dirección de memoria.

Dos, copia superficial

1. Definición y principio de copia superficial

La copia superficial se refiere a la creación de nuevos datos que tienen una copia exacta de los valores de atributos de datos originales.

Si el atributo es un tipo primitivo, se copia el valor del tipo primitivo. Si el atributo es un tipo de referencia, la dirección de memoria se copia

Es decir, la copia superficial es para copiar una capa y el tipo de referencia profunda comparte la dirección de memoria

2. El método de implementación de copia superficial

(1) Implementación recursiva manuscrita

            // 手写实现浅拷贝
            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);

Los resultados de la impresión son los siguientes

(2) Use la sintaxis de expansión para realizar una copia superficial

            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 fusiona objetos

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

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

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

(5).Usando Array.prototype.contact()

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

3. Copia profunda

1. Definición y principio de copia profunda

  La copia profunda crea una nueva pila. Las propiedades de los dos objetos son idénticas, pero corresponden a dos direcciones diferentes. La modificación de las propiedades de un objeto no cambiará las propiedades del otro objeto.

2. Método de implementación de copia profunda

(1).Implementación recursiva de copia profunda

el primer método

            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);

El segundo método es usar Object.entries(obj) hábilmente para recorrer las propiedades y valores de los objetos.

            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);

La salida es la misma, de la siguiente manera:

(2).JSON.parse(JSON.stringify(objeto a copiar))

            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) El primer parámetro de $.extend() en .jQuery se establece en verdadero para copia profunda y falso para copia superficial (para introducir la biblioteca JQuery)

            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) Introducir loadsh y proporcionar implementación cloneDeep

Pasos para implementar una copia profunda usando la biblioteca loash en vue

  1. instalar loadsh npm i --save  lodash
  2. Introducir loadsh import _ from 'lodash'
  3. Llame directamente al método de la biblioteca loadsh const newObj = _.cloneDeep(this.obj)

Supongo que te gusta

Origin blog.csdn.net/qq_63299825/article/details/131003216
Recomendado
Clasificación