premisa:
La copia profunda y la copia superficial son solo para tipos de datos de referencia como Objeto y Matriz.
1. Pila de memoria
Vea otro tipo de datos de blog y almacenamiento de pila específicamente
2. Copia superficial y copia profunda
Los diagramas esquemáticos de copia profunda y copia superficial son aproximadamente los siguientes:
La copia superficial solo copia el puntero a un objeto, no al objeto en sí. Los objetos antiguos y nuevos aún comparten la misma memoria. Pero una copia profunda creará otro exactamente el mismo objeto. El nuevo objeto no comparte memoria con el objeto original. Modificar el nuevo objeto no cambiará el objeto original.
La diferencia entre asignación y copia superficial
Asignación:
Al asignar un objeto a una nueva variable, en realidad es la dirección del objeto en la pila, no los datos en el montón. Es decir, dos objetos apuntan al mismo espacio de almacenamiento. No importa qué objeto cambie, en realidad es el contenido del espacio de almacenamiento modificado. Por tanto, los dos objetos están vinculados.
Copia superficial:
La copia superficial es una copia bit a bit de un objeto. Crea un nuevo objeto que tiene una copia exacta de los valores de atributo del objeto original. Si el atributo es un tipo básico, se copia el valor del tipo básico; si el atributo es una dirección de memoria (tipo de referencia), se copia la dirección de memoria, por lo que si un objeto cambia esta dirección, afectará al otro objeto. Es decir, el constructor de copia predeterminado solo realiza una copia superficial del objeto (copia miembro por miembro a su vez), es decir, solo copia el espacio del objeto sin copiar recursos.
Copia profunda manuscrita (recursiva):
/**
* 深拷贝
*/
const obj1 = {
age: 20,
name: 'xxx',
address: {
city: 'beijing'
},
arr: ['a', 'b', 'c']
}
const obj2 = deepClone(obj1)
obj2.address.city = 'shanghai'
obj2.arr[0] = 'a1'
console.log(obj1.address.city)
console.log(obj1.arr[0])
/**
* 深拷贝
* @param {Object} obj 要拷贝的对象
*/
function deepClone(obj = {
}) {
if (typeof obj !== 'object' || obj == null) {
// obj 是 null ,或者不是对象和数组,直接返回
return obj
}
// 初始化返回结果
let result
if (obj instanceof Array) {
result = []
} else {
result = {
}
}
for (let key in obj) {
// 保证 key 不是原型的属性
if (obj.hasOwnProperty(key)) {
// 递归调用!!!
result[key] = deepClone(obj[key])
}
}
// 返回结果
return result
}