JavaScript 手写深拷贝

117 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情

前言

js深拷贝是相对于浅拷贝而已的,所谓的深浅拷贝就是对象在复制的时候,引用类型的值复制前后是否共用一个内存地址。

如果是共用一个内存地址,那就是浅拷贝。修改复制前(后)对象的值,修改后(前)对象的值也会发生相对应的变化,因为它们实际上就是一个对象。

如果是不共用一个内存地址,那就是深拷贝。深拷贝会在内存中开辟一个新的区域存放新对象。修改复制前(后)对象的值,修改后(前)对象的值不会发生相对应的变化,因为它们实际上是两个对象。

浅拷贝图示

图片来源于网络侵权必删.png

深拷贝图示

图片来源于网络侵权必删.png

三步实现深拷贝

第一步:判断入参是值类型还是引用类型,值类型直接返回

            if(typeof obj !== 'object' || obj == null){
                return obj;
            }

第二步:判断是数组还是对象,用空变量接收结果

            if( obj instanceof Array){
                result = [];
            }else{
                result = {};
            }

第三步:递归调用

            if(obj.hasOwnProperty(key)){
                // 递归调用
                result[key] = deepClone(obj[key]);
            }

示例代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>深拷贝</title>
</head>
<body>
    <script>
        const obj1 = {
            name: "张三",
            address: {
                city: "北京",
                a:['1']
            }
        };
        //进行深拷贝
        const obj3 = deepClone(obj1);
        //修改深拷贝的数据
        obj3.address.city = "南京";
        //打印拷贝模板数据
        console.log('obj1',obj1);
        //打印修改后的深拷贝数据
        console.log('obj3',obj3);

        // obj = {}默认值
        function deepClone(obj = {}){
            // 判断传入的 obj 是不是数组或对象,不是直接返回 obj
            if(typeof obj !== 'object' || obj == null){
                return obj;
            }
            let result;
            // 判断是不是数组
            if( obj instanceof Array){
                result = [];
            }else{
                result = {};
            }
            for(let key in obj){
                // hasOwnProperty()方法:检测一个属性是否是对象的自有属性
                if(obj.hasOwnProperty(key)){
                    // 递归调用
                    result[key] = deepClone(obj[key]);
                }
            }
            return  result;
        }
    </script>
</body>
</html>

控制台输出

在这里插入图片描述

本文到此结束

如果大家还有什么其他想法,欢迎在评论区交流!