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
1. Definición y principio de copia superficial
2. El método de implementación de copia superficial
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
- instalar loadsh npm i --save lodash
- Introducir loadsh import _ from 'lodash'
- Llame directamente al método de la biblioteca loadsh const newObj = _.cloneDeep(this.obj)