• 深拷贝、浅拷贝的方法


    目录

    浅拷贝

    深拷贝


    深拷贝浅拷贝概念: 

    1. 深浅拷贝出现的前提: 应用类型的数据(对象和数组)
    2. 深拷贝就是把目标对象里面的数据一个一个都复制下来,创建出一个一模一样的,存放地
    3. 址不一样,互不影响。就像真假美猴王。改变其中一个对象中的内容,另一个对象不会受
    4. 到任何影响。
    5. 浅拷贝就是单纯的复制内存地址,并没有复制对象本身,新旧两个都共享同一个内存。一荣
    6. 俱荣一损共损的样子,任何一个对象里改变某一个属性值,那么另一个也会随之发生改变
    7. **区别:**浅拷贝只能复制第一层,想要深度拷贝的话就要用到深拷贝了

    深拷贝和浅拷贝的区别

    1.浅拷贝: 将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用

    2.深拷贝: 创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”

    接下来我们就以下面这个obj1对象为例子,进行深浅拷贝的演示

    1.   const obj1 = {
    2.     a: 1,
    3.     b: undefined,
    4.     arr: [1, 2, 3],
    5.     fun: () => {}
    6.   }

    浅拷贝

     1.Object.assign()方法

    const obj2 = Object.assign({},obj1)


    缺点:这里就会发现使用Object.assign()只能深拷贝一级属性,二级以上的属性(引用类型)就是浅拷贝了

    2.扩展运算符

    const obj2 = {...obj1}

     

    缺点:这个方法和上面使用Object.assign()方法使用的结果都是一样的。只能深拷贝一级属性,二级以上属性(引用类型)就是浅拷贝了

    3.arrayObject.slice(start,end)、arrayObject.concat(arrayX,...,arrayX)

    用法:

    arrayObject.slice(start,end)
    
    • Object.assign()
    • 函数库lodash的_.clone方法
    • 展开运算符…
    • Array.prototype.concat()
    • Array.prototype.slice()

    深拷贝

    1.写一个递归(推荐,比较完美的解决方案)
    封装一个DeepClone的深拷贝函数

    1.   function DeepClone(data) {
    2.     const newData = Array.isArray(data) ? [] : {}
    3.     for (let key in data) {
    4.       if (data[key] && typeof data[key] === 'object') {
    5.         newData[key] = DeepClone(data[key])
    6.       } else {
    7.         newData[key] = data[key]
    8.       }
    9.     }
    10.     return newData
    11.   }
    1. //deepClone 深拷贝
    2. function deepClone(source) {
    3. if (!source || typeof source !== 'object') {
    4. return source;
    5. }
    6. const targetObj = source.constructor === Array ? [] : {};
    7. for (const keys in source) {
    8. if (source.hasOwnProperty(keys)) {
    9. if (source[keys] && typeof source[keys] === 'object') {
    10. targetObj[keys] = source[keys].constructor === Array ? [] : {};
    11. targetObj[keys] = deepClone(source[keys]);
    12. } else {
    13. targetObj[keys] = source[keys];
    14. }
    15. }
    16. }
    17. return targetObj;
    18. }

    //调用他

    const obj2 = DeepClone(obj1)

     2.用for…in实现遍历和复制

    1. function deepClone(obj) {
    2. let result = typeof obj.splice === "function" ? [] : {};
    3. if (obj && typeof obj === 'object') {
    4. for (let key in obj) {
    5. if (obj[key] && typeof obj[key] === 'object') {
    6. result[key] = deepClone(obj[key]);//如果对象的属性值为object的时候,递归调用deepClone,即在吧某个值对象复制一份到新的对象的对应值中。
    7. } else {
    8. result[key] = obj[key];//如果对象的属性值不为object的时候,直接复制参数对象的每一个键值到新的对象对应的键值对中。
    9. }
    10. }
    11. return result;
    12. }
    13. return obj;
    14. }
    15. let testArray = ["a", "b", "c", "d"];
    16. let testRes = deepClone(testArray);
    17. console.log(testRes);
    18. console.log(typeof testRes[1]);
    19. let testObj = {
    20. name: "weiqiujuan",
    21. sex: "girl",
    22. age: 22,
    23. favorite: "play",
    24. family: {brother: "son", mother: "haha", father: "heihei"}
    25. };
    26. let testRes2 = deepClone(testObj);
    27. testRes2.family.brother = "weibo";
    28. console.log(testRes2);

    3.利用数组的Array.prototype.forEach进copy

    1. let deepClone = function (obj) {
    2. //Object.getPrototypeOf() 方法返回指定对象的原型(内部[[Prototype]]属性的值)。
    3. let copy = Object.create(Object.getPrototypeOf(obj));
    4. //**Object.getOwnPropertyNames()**方法返回一个由指定对象的所有自身属性的属性名
    5. //(包括不可枚举属性但不包括 Symbol 值作为名称的属性)组成的数组。
    6. let propNames = Object.getOwnPropertyNames(obj);
    7. propNames.forEach(function (items) {
    8. // 方法返回指定对象上一个自有属性对应的属性描述符。
    9. //(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)
    10. let item = Object.getOwnPropertyDescriptor(obj, items);
    11. Object.defineProperty(copy, items, item);
    12. });
    13. return copy;
    14. };
    15. let testObj = {
    16. name: "weiqiujuan",
    17. sex: "girl",
    18. age: 22,
    19. favorite: "play",
    20. family: {brother: "wei", mother: "haha", father: "heihei"}
    21. }
    22. let testRes2 = deepClone(testObj);
    23. console.log(testRes2);

    4.JSON转换方法

    1.   const obj1 = {
    2.     a: 1,
    3.     b: undefined,
    4.     arr: [1, 2, 3],
    5.     fun: () => {}
    6.   }
    const obj2 = JSON.parse(JSON.stringify(obj1)) 

    //这个方法可以,只不过function和undefined这种情况下无法复制

    缺点:你看到这里就会发现数据类型是 function 和 undefined 情况下无法复制,其他的都可以进行深层次的拷贝

    5.loadash函数库
    函数库lodash,也有提供_.cloneDeep用来做深拷贝6.

    1. let lodash = require('lodash');
    2. let list = [{ name: 'Tom' }];
    3. let copyList = lodash.cloneDeep(list);
    4. copyList[0].name = 'Jerry'
    5. console.log(list[0].name);      // Tom
    6. console.log(copyList[0].name);      // Jerry
  • 相关阅读:
    python实现炫酷的屏幕保护程序
    HTML+CSS大作业 格林蛋糕(7个页面) 餐饮美食网页设计与实现
    编译器优化记录(死代码消除+“激进的”死代码消除)
    国产AI芯,飞凌RK3568核心板在人脸识别终端的应用方案
    专业英语历年题
    语音信号处理-基础(四):时域音频特征及Python实现
    干货!英语常用口语1000句大全(完整版)!
    web基础和http协议
    代码随想录33|509. 斐波那契数,70. 爬楼梯,746. 使用最小花费爬楼梯, 34. 在排序数组中查找元素的第一个和最后一个位置
    使用grabit分析mysql数据库中的数据血缘关系
  • 原文地址:https://blog.csdn.net/weixin_51225684/article/details/128130401