[Frontend] Copia profunda y superficial

1. Revisa los tipos de variables

tipo básico

booleano (bool)

número

cadena

nulo

indefinido

tipo de referencia

objeto

función

matriz

Almacenamiento de tipos primitivos y tipos de referencia

Los tipos básicos generalmente se almacenan en la pila (la pila es pequeña) 

  1. Una vez que se fija el tamaño de la pila, puede causar un desbordamiento
  2. La pila es generalmente el primero en entrar, el último en salir.
  3. La dirección del montón utilizada para almacenar tipos básicos y tipos de referencia.
  4. corre rapido

Los tipos de referencia generalmente se almacenan en el montón (tamaño del montón)

  1. El tamaño del montón no está confirmado y se puede expandir
  2. JS no puede manipular directamente los datos del montón
  3. Almacenamiento fuera de servicio
  4. Es lento porque su tamaño no es fijo y el orden no es fijo

Diagrama de pila

Contenido de la pila Cuando el programa termina de ejecutarse, la pila está vacía

Sin embargo, si falta el contenido del montón, debe estar vacío. Puede parecer que no hay ningún puntero al contenido del montón, por lo que se convertirá en basura.

Por lo tanto, debemos apuntar manualmente a nulo para permitir que se destruya.

Dos, copia superficial

Copia profunda y superficial en dos casos Tipo de referencia Tipo básico

Los tipos básicos son copias profundas

La mayoría de los tipos de referencia son copias superficiales y también pueden convertirse en copias profundas.

La dirección de la copia profunda es diferente, uno cambia al otro y no sigue el cambio, es decir, la dirección del contenido de la copia profunda es diferente

La dirección de la copia superficial es la misma, una cambia y la otra cambia en consecuencia, es decir, la copia superficial copia la dirección

 
 
  1. 深拷贝
  2. let a = 10;
  3. let b = a;
  4. console.log(1,a,b,a===b);
  5. a = 88;
  6. console.log(2,a,b,a===b);
  7. console.log("======================");
  8. 浅拷贝
  9. let obj1 = {
  10. n : 88
  11. }
  12. let obj2 = obj1;
  13. console.log(1,obj1,obj2,obj1===obj2);
  14. obj1.a = 99;
  15. console.log(2,obj1,obj2,obj1===obj2);
 
 
  1. 实现深拷贝 array object
  2. 1.JSON.stringify JSON.parse
  3. let obj1 = {
  4. n : 88
  5. }
  6. let obj2 = JSON.parse(JSON.stringify(obj1)); //深拷贝
  7. console.log(1,obj1,obj2,obj1===obj2);
  8. obj1.a = 99;
  9. console.log(2,obj1,obj2,obj1===obj2);
  10. 2. ... 解构
  11. let arr1 = [1,5,6,7];
  12. let arr2 = [...arr1];
  13. console.log(1,arr1,arr2,arr1===arr2);
  14. arr1[0] = "222"
  15. console.log(2,arr1,arr2,arr1===arr2);
 
 
  1. // 伪拷贝 一般情况下是 第一层深拷贝 后面层浅拷贝
  2. let arr1 = [1,2,3,[6,7,8]];
  3. let arr2 = arr1.slice();
  4. console.log(1,arr1,arr2,arr1 === arr2);
  5. arr1[0] = 180;
  6. arr1[3][0] = 666;
  7. console.log(2,arr1,arr2,arr1 === arr2);
  8. let arr1 = [1,2,3,[6,7,8]];
  9. let arr2 = arr1.concat();
  10. console.log(1,arr1,arr2,arr1 === arr2);
  11. arr1[0] = 180;
  12. arr1[3][0] = 666;
  13. console.log(2,arr1,arr2,arr1 === arr2);
 
 
  1. let menu1 = {
  2. menu: "菜单",
  3. item:{
  4. type: "menu",
  5. name: "子菜单"
  6. }
  7. }
  8. // Object.assign(目标,源)
  9. let menu2 = Object.assign({},menu1)
  10. console.log(1,menu1,menu2,menu1 === menu2);
  11. menu1.menu = "编辑"
  12. menu1.item.name = "保存"
  13. console.log(2,menu1,menu2,menu1 === menu2);

Qué hacer si quieres resolver la copia real

Aplane el método de pensamiento multicapa anidado para aplanar el pensamiento recursivo para él

pensamiento recursivo

Ordinario como normal

La profundidad (tipo de referencia) se procesa recursivamente hasta que no haya tipos de referencia...

 
 
  1. let woniu = {
  2. name: "张三",
  3. age: 8,
  4. school: [
  5. {
  6. id: 1,
  7. name: "清华校区"
  8. },
  9. {
  10. id: 2,
  11. name: "北大校区"
  12. },
  13. {
  14. id: 3,
  15. name: "上交校区"
  16. },
  17. {
  18. id: 4,
  19. name: "国科大校区"
  20. }
  21. ],
  22. subject: {
  23. web: "web前端",
  24. java: "java后端",
  25. python: "python",
  26. ui: "设计"
  27. }
  28. }
  29. function copyData(source) {
  30. // 定义一个容器 容器需要根据源来决定 源是对象 你就是你对象 源是数组你就是数组
  31. let result = Array.isArray(source) ? [] : {};
  32. for (const item in source) { // 遍历源 对象与数组的统一遍历方式是 for in
  33. if (typeof source[item] === "object") { //区分引用类型与普通类性别 引用类型继续处理(遍历)基本类型直接返回
  34. result[item] = copyData(source[item])
  35. } else {
  36. result[item] = source[item];
  37. }
  38. }
  39. return result; // 最终将结果返回
  40. }
  41. let fanyun = copyData(woniu);
  42. console.log(1,woniu,fanyun);
  43. woniu.subject.web = "web大前端"
  44. woniu.school[0].name = "总校区"
  45. console.log(2,woniu,fanyun);

 

Supongo que te gusta

Origin blog.csdn.net/wodegeCSDN/article/details/130563612
Recomendado
Clasificación