手写深拷贝:

文章介绍了三种JavaScript实现深拷贝的方法:使用JSON.parse和JSON.stringify,以及通过递归函数创建深拷贝。分别展示了简单的对象拷贝和处理包含复杂结构(如嵌套对象、数组、函数等)的深拷贝实现。

工作版本:

// JSON.parse(JSON.stringify) :深拷贝

        var origin_data = { a: 1, b: 2, c: [1, 2, 3] }
        var copy_data = JSON.parse(JSON.stringify(origin_data))

乞丐面试版:

 var p = {
        "id":"007",
        "name":"刘德华",
        "wife": {
            "id":"008",
            "name":"刘德的妻子",
            "address": {
                "city":"北京",
                "area":"海淀区"
            }
        }
    }
//写函数
function copyObj(obj) {
        let newObj = {};
        for (let key in obj) {
            if (typeof obj[key] == 'object') {
             newObj[key] = copyObj(obj[key]);//如:key是wife,引用类型,那就递归
            } else {
             newObj[key] = obj[key];//基本类型,直接赋值
            }
        }
        return newObj;
}
let pNew = copyObj(p);

正常版本:


 let arr = [5, 4, 9, 8]
        let obj1 = {
            name: 'xxx',
            sex: '男',
            like: ['红色', '蓝色'],
            book: {
                title: 'js程序',
                price: '88'
            }
        }
        function deepClone(obj) {
            //查看要拷贝的对象是数组还是对象,如果数组创建空数组,是对象创建空对象
            let newObj = obj instanceof Array ? [] : {}
            for (let k in obj) {
                //K属性名  obj[k]值
                //判断当前每个元素是否是对象或者数组 
                //如果还是对象,继续递归拷贝
                //是值,直接添加到新创建的对象或者数组里
                if (typeof obj[k] === 'object') {
                    //递归拷贝完 放入到新对象的属性
                    newObj[k] = deepClone(obj[k])
                } else {
                    //否则是值, 直接添加到新建的 newObj中
                    newObj[k] = obj[k]
                }
            }
            //返回新对象
            return newObj
        }
 
        var obj2 = deepClone(obj1)
        obj2.like.push('紫色')
        obj2.book.price = 999
        console.log(obj1);
        console.log(obj2);

豪华版本:

 <script>
        let obj =
        {
            uname: '小妲己',
            age: 18,
            hobby: ['打野', '蹲草丛', '魅惑'],
            team: ['坤坤', '波波', '迪迪', '宏宏'],
            company: {
                add1: '科技二路',
                add2: '科技六路',
                add3: '立人科技',
                add4: ['a座', 'b座', 'c座']
            },
            un: undefined,
            nu: null,
            show: function () {
                console.log('秀儿');
            },
            reg: /^[0-9]$/
        }


        // 深拷贝实现思路:遍历源数据,跟据属性值分为3种情况:1. 如果是对象或者数组,就继续遍历,直到得到基本类型;2. 如果是函数,就调用bind方法复制一个新的方法即可; 3. 如果是基本数据类型,就直接赋值即可

        /* 
            分析:
                => 1. 拷贝的源数据可以是数组,也可以是对象, 需要使用for...in遍历
                => 2. 判断数据类型的方法:Object.prototype.toString.call()
                => 3. 将数据类型判断的方法封装成函数:1. 判断是否是 a数组, b对象, c方法

            
        */

        // 1. 封装判断数据类型的函数
        function getType(data) {
            return Object.prototype.toString.call(data)
        }

        // 2. 封装对数组的判断
        function isArray(data) {
            return getType(data) === '[object Array]'
        }

        // 3. 封装对对象的判断
        function isObj(data) {
            return getType(data) === '[object Object]'
        }

        // 4. 封装对函数的判断
        function isFunction(data) {
            return getType(data) === '[object Function]'
        }

        // 5. 深拷贝函数封装
        function cloneDeep(target) {
            // 5.1 判断拷贝的是数组或者对象
            let newTarget = isArray(target) ? [] : {}
            // 5.2 遍历源数据
            for (let key in target) {
            // console.log(key);

                // 如果是对象或者数组,就继续遍历
                if (isArray(target[key]) || isObj(target[key])) {
                    // 这里使用递归函数的原因:拷贝的内层数据也可能是数组或对象,需要使用递归函数继续遍历,如果是基本类型,就直接赋值
                    newTarget[key] = cloneDeep(target[key])
                } else if (isFunction(target[key])) {
                    // 如果是函数,就调用bind方法复制一个新的方法即可
                    newTarget[key] = target[key].bind()
                } else {
                    // 如果是基本数据类型,就直接赋值即可
                    newTarget[key] = target[key]
                }
            }
            return newTarget
        }

        let newObj = cloneDeep(obj)

        console.log(newObj);
    </script>

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值