JS中的深拷贝和浅拷贝

张春  论坛元老 | 2024-7-18 07:09:36 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1027|帖子 1027|积分 3081

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
一.JS中的浅拷贝

       JS中的浅拷贝会在栈内存中开辟另外一块空间   ,并且把被拷贝对象的栈内存数据完全拷贝到新开辟的空间中,即根本数据类型的值会被完全拷贝而引用数据类型的浅拷贝则是拷贝了指向堆内存的地址。
二.JS中实现浅拷贝的方法

       2.1扩展运算符

              扩展运算符的根本语法为:let newObj={...obj}
代码示例如下: 
  1. let obj={
  2.             a:1,
  3.             b:2,
  4.             c:3
  5.         }
  6.         let newObj={...obj};
  7.         newObj.b=5;
  8.         console.log(obj);
  9.         console.log(newObj);
复制代码
运行结果如下: 
 
        2.2Object.assign()方法

Object.assign()方法吸收两个参数,一个是目的对象,一个是源对象,使用assign方法必要留意的是它不会拷贝对象的继承属性,不会拷贝对象的不可枚举的属性,但是它可以拷贝Symbol类型的属性。
  1. let a = {
  2.             x: 1,
  3.             y: 2,
  4.             z: {
  5.                 num: 3
  6.             }
  7.         };
  8.         let b = {};
  9.         Object.assign(b, a);
  10.         b.y = 10;
  11.         console.log(a);
  12.         console.log(b);
复制代码

        2.3Array.slice()方法

              slice()方法返回一个新的数组对象,这一对象是一个由start和end决定的原数组的浅拷贝(包括start,不包括end),其中start和end表现的是原数组的索引。原始数组不会被改变。
  1. let a1=[1,2,3,4];
  2.         let b=a1.slice();
  3.         b[2]=10;
  4.         console.log(a1);
  5.         console.log(b);
复制代码
 
         2.4Array.concat()方法

                Array.concat()方法用于归并两个大概是多个数组,这个方法不会改变原来的数组,而是返回一个新数组,用于实现数组的浅拷贝。
  1. let a1=[1,2,3,4];
  2.         let b=a1.concat(a1);
  3.         console.log(a1);
  4.         console.log(b);
复制代码
 
三.JS中的深拷贝

        JS中对象的深拷贝指的是其属性与其拷贝的源对象的属性不共享雷同的引用的副本。使用深拷贝会创建一个对象及其所有子对象(嵌套对象)的完全独立的副本,新对象与源对象互不影响
四.实现深拷贝的方法

    4.1使用JSON.parse(JSON.stringfy(object)) 方法

  1. let ingredients_list = ["noodles", { list: ["eggs", "flour", "water"] }];
  2.         let ingredients_list_deepcopy = JSON.parse(JSON.stringify(ingredients_list));
  3.         console.log(ingredients_list);
  4.         console.log(ingredients_list_deepcopy);
复制代码
  1. // 改变 ingredients_list_deepcopy 中 'list' 属性的值。
  2. ingredients_list_deepcopy[1].list = ["rice flour", "water"];
  3. // ingredients_list 的“list”属性不会发生变化。
  4. console.log(ingredients_list[1].list);
  5. // Array(3) [ "eggs", "flour", "water" ]
复制代码
        4.2使用递归的方式,手动拷贝对象的每一层   

  1. function deepCopy(obj){
  2.     let objClone=Array.isArray(obj)?[]:{};
  3.     if(obj&&typeof obj=='object'){
  4.         for(const key in obj){
  5.             //判断obj子元素是否为对象,如果是则递归复制
  6.             if(obj[key]&&typeof obj[key]==='object'){
  7.                 objClone[key]=deepCopy(obj[key]);
  8.             }
  9.             else{
  10.             //如果不是,简单复制
  11.             objClone[key]=obj[key];
  12.             }
  13.         }
  14.     }
  15.     return objClone;
  16. }
复制代码
        4.3使用函数库lodash 

               lodash函数库中提供了_.cloneDeep方法来实现深拷贝
  1. let _ = require('lodash');
  2.         let obj = {
  3.             a:10,
  4.             b:{f:{g:20}},
  5.             c:[10,20,30]
  6.         };
  7.         let newObj = _.cloneDeep(obj);
  8.         console.log(obj.b.f === newObj.b.f); // false
复制代码
五.总结

     浅拷贝实现的是对基础数据类型的拷贝,并且数据 只有单一的一层,而深拷贝用来拷贝具有嵌套层级的引用数据类型。对于根本数据类型来说,深拷贝和浅拷贝实现的效果一样;而对于引用数据类型来说,深拷贝可以实现操作该数据,并且不会影响到源数据的效果。
 
         
                


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

张春

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表