• 浅拷贝和深拷贝


    对于网上深浅拷贝的定义观点各不一致,有点误人子弟!
    在此写这篇文章也是为了帮助大家更好的做区分和理解

    区分

    浅拷贝是指对象复制的时候只复制一层
    深拷贝是指复制对象的所有层级,不共享内存(修改新对象不会改到原对象)

    对象

    浅拷贝

    1. 通过引用赋值

    const obj = { name: '张三' };
    const newObj = obj; 
    
    • 1
    • 2

    2. 通过Object.assign()

    const obj = { name: '张三' };
    const newObj = Object.assign(obj,{}); 
    
    • 1
    • 2

    3. 通过…拓展运算符 (拷贝后的对象第一层中基础类型修改了是不会影响到原对象的)

    const obj = { name: '张三' };
    const newObj = {...obj}; 
    
    • 1
    • 2

    4. for in 复制第一层(拷贝后的对象第一层中基础类型修改了是不会影响到原对象的)

    const obj = { name: '张三' };
    const newObj = {}; 
    for(let key in obj){
    	newObj[key] = obj[key]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    深拷贝

    1. 通过JSON, 会造成方法丢失

    const obj = { name: '张三' };
    const newObj = JSON.parse(JSON.stringify(obj)); 
    
    • 1
    • 2

    2. 递归;缺点:性能不好,占用内存

    简易版,还有很多因素没考虑到(慎用)

        function deepClone(obj) {
        	// 数组, 对象, null通过 typeof 检测都为 object
            if ((typeof obj !== 'object') || obj === null) return obj;
            let result = new obj.constructor // 另一种方式 Array.isArray(obj) ? [] :{}
            for (let key in obj) {
                // 判断对象自身属性中是否具有指定的属性
                if (obj.hasOwnProperty(key)) {
                    result[key] = deepClone(obj[key]) // 递归
                }
            }
            return result
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3. 通过structuredClone

    需考虑浏览器兼容问题,Function和Dom节点拷贝不了

    const obj = { name: '张三' };
    const newObj = structuredClone(obj)
    
    • 1
    • 2

    4. 使用Immutable.js

    5. 使用lodash库中的_.cloneDeep方法

    数组

    浅拷贝

    1. 通过引用赋值

    const arr = [ 1, 2 ]
    const newArr = arr
    
    • 1
    • 2

    2. 通过slice(拷贝后的对象第一层中基础类型修改了是不会影响到原对象的)

    const arr = [ 1, 2 ]
    const newArr = arr.slice()
    
    • 1
    • 2

    3. 通过…拓展运算符(拷贝后的对象第一层中基础类型修改了是不会影响到原对象的)

    const arr = [ 1, 2 ]
    const newArr = [...arr]
    
    • 1
    • 2

    4. 通过concat(拷贝后的对象第一层中基础类型修改了是不会影响到原对象的)

    const arr = [ 1, 2 ]
    const newArr = arr.concat()
    
    • 1
    • 2

    5. 遍历复制数组 for 、while、map、 filter、 reduce(拷贝后的对象第一层中基础类型修改了是不会影响到原对象的)

    深拷贝

    1. 通过JSON, 会造成方法丢失

    const arr = [ 1, 2 ]
    const newArr = JSON.parse(JSON.stringify(arr)); 
    
    • 1
    • 2

    2. 递归;缺点:性能不好,占用内存

    3. 通过structuredClone

    4. 使用Immutable.js

    5. 使用lodash库中的_.cloneDeep方法

  • 相关阅读:
    【每日一题】—— C. Anonymous Informant(Codeforces Round 908 (Div. 2))(思维题)
    C++遍历(traversal)总结
    KY36 中位数
    [附源码]java毕业设计超市收银系统
    Github每日精选(第11期):端对端的数据传输croc
    spring boot 引入hive
    第九章-项目资源管理
    尚医通-微信支付
    解决“413 Request Entity Too Large”错误 代表请求包太大,服务器拒绝响应
    windows10使用wheel安装tensorflow2.13.0/2.10.0(GPU版本) (保姆级教程)
  • 原文地址:https://blog.csdn.net/qq_45487080/article/details/126778542