[前端]深浅拷贝

一、回顾变量类型

基础类型

boolean(bool)

number

string

null

undefined

引用类型

object

​ function

​ array

基本类型与引用类型的存储

基本类型一般存储在 栈 (栈小) 

  1. 栈一旦确认 大小就固定 可能会造成溢出
  2. 栈一般是先进后出
  3. 用于存储基础类型以及引用类型的堆地址
  4. 运行速度快

引用类型一般存储在 堆(堆大)

  1. 堆大小不确认 可以扩展
  2. 不允许js直接操作堆数据
  3. 无序存储
  4. 由于其大小不固定 顺序不固定 导致 速度慢

堆栈示意图

栈内容当程序运行完毕 栈就空了

但是堆内容不见的一定就空 可能会出现 没有任何指针指向堆内容 导致都变成垃圾

所以我们需要手动指向 null让其销毁

二、深浅拷贝

深浅拷贝分两种情况 引用类型 基础类型

基础类型都是深拷贝

引用类型 大多数是浅拷贝 也可以变成深拷贝

深拷贝 地址不同 一个改变另一个并不跟随发生变化就是深拷贝 拷贝内容 地址不同

浅拷贝 地址相同 一个改变另一个随之改变 就是浅拷贝 拷贝的是地址

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

想要解决真正意义上的拷贝咋办

扁平化 嵌套的多层想办法给他变成地扁平化 递归思想

递归思想

普通的 按正常处理

深度的(引用类型 )按递归处理 直到没有引用类型为止··

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

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李桥桉

支持一下作者

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值