• 深拷贝和浅拷贝的区别是什么?实现一个深拷贝


    JS的基本数据类型

    • 基本数据类型:String,Boolean,Number,Undefined,Null;
    • 引用数据类型:Object(Array,Date,RegExp,Function);

    浅拷贝

    • 浅拷贝是会将对象的每个属性进行依次复制,但是当对象的属性值是引用类型时,实质复制的是其引用,当引用指向的值改变时也会跟着变化。
    • Object.assign、 扩展运算符 ... 、 Array.prototype.slice()、 Array.prototype.concat() 等

    深拷贝

    • 深拷贝复制变量值,对于引用数据,则递归至基本类型后,再复制。
    • 深拷贝后的对象与原来的对象是完全隔离的,互不影响,对一个对象的修改并不会影响另一个对象

    示例:

        let obj = {
            name : 'Michael',
            age  :  18 ,
            others : {
                hobbies : ['basketball','gambling'],
                team : 'Bulls',
            },
        }
        let [newObj,newObj2] = [Object.assign({},obj),{...obj}]
        
        obj.name = 'Kobe';
        obj.others.team = 'Lakers';
    
        console.log(obj)
    console.log(newObj)
    console.log(newObj2)

    我们能看出:

    • newObj及newObj2的others为引用数据类型,因此与原对象obj的属性值指向同一块内存地址,修改原对象的others内的内容,新对象的内容也会更改
    •  第一层的属性值为基本数据类型(String),修改原对象,对新对象不造成影响

    因此 深拷贝与浅拷贝的区别为

    • 浅拷贝当第一层的属性值是基本数据类型时,新的对象和原对象互不影响,但是如果第一层的属性值是引用数据类型时,那么新对象和原对象的属性值其指向的是同一块内存地址。
    • 深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象;

    深拷贝的代码实现

    1. 如果是基本数据类型,直接返回
    2. 如果是复杂数据类型,递归。
    3. 如果是RegExp 或者 Date 类型,返回对应类型
       let obj = {
            name: 'Michael',
            age: 18,
            others: {
                hobbies: ['basketball', 'gambling'],
                team: 'Bulls',
            },
        }
        // 递归拷贝
        function deepClone(obj) {
            if (obj instanceof RegExp) return new RegExp(obj);
            if (obj instanceof Date) return new Date(obj);
            if (obj === null || typeof obj !== 'object') return obj //如果不是引用类型则直接返回
            let newObj = new obj.constructor();    //如果obj是数组,newObj=[];如果obj是对象,newObj={}
            for (let key in obj) {
                if (obj.hasOwnProperty(key)) {    //是否是自身的对象
                    newObj[key] = deepClone(obj[key])   //赋值
                }
            }
            return newObj
        }
        const copyObj = deepClone(obj);
        obj.others.team = 'Lakers';
        console.log(obj,copyObj)

    经比较:深拷贝后修改原对象的值并不会改变新对象的值

  • 相关阅读:
    继承项目第13周项目1基类中成员的访问限定符和派生类的继承方式
    架构业务wait和sleep区别狭义jiavaBean规范,三层架构模式
    文件文本编辑器ASP.net使用CKEditor(html文本编辑器)
    彩信对象android(5)_发彩信操作
    方法接口UML统一建模语言,java中七种设计原则,
    jquery实现jQuery实现图片轮播效果,jQuery实现焦点新闻
    设备文件BSP及嵌入式驱动开发笔记
    Invalidate
    C#集合类使用范例
    判断一段程序是由C 编译程序还是由C++编译程序编译的
  • 原文地址:https://www.cnblogs.com/dajuyiding/p/11367883.html
Copyright © 2020-2023  润新知