美文网首页
js深拷贝和浅拷贝

js深拷贝和浅拷贝

作者: 小溪流jun | 来源:发表于2021-09-26 08:36 被阅读0次
    <!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>
            /*
                +深拷贝和浅拷贝
                    ==>存储的是该对象在栈中引用,真实的数据存放在堆内存里
                    ==>浅拷贝(shallowCopy)只是增加了一个指针指向已存在的内存地址(地址不变)
                    ==>深拷贝(deepCopy)是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存(开辟一个新的地址)
    
                    实现深复制的方法
                    JSON.parse(JSON.stringify())
            */
            //浅复制
            function shallowCopy(obj) {
                if (typeof obj !== 'object') return
    
                let newObj = obj instanceof Array ? [] : {}
                for (let key in obj) {
                    //对象.hasOwnProperty(key):判断对象是否包含特定的自身(非继承)属性
                    if (obj.hasOwnProperty(key)) {
                        newObj[key] = obj[key]
                    }
                }
                return newObj
            }
    
            //简单版的深复制
            function deepClone(obj) {
                if (typeof obj !== 'object') return;
                var newObj = obj instanceof Array ? [] : {};
                for (var key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        newObj[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key];
                    }
                }
                return newObj;
            }
    
            var obj1 = { a: 1, arr: [2, 3] };
            let obj2 = shallowCopy(obj1)
            console.log(obj1)
            console.log(obj2)
            //改变obj2中的arr,obj1也会改变
            obj2.arr[1] = 5;
            console.log(obj1)
            console.log(obj2)
    
            //复杂版深克隆:基于简单版的基础上,还考虑了内置对象比如 Date、RegExp 等对象和函数以及解决了循环引用的问题。
            const isObject = (target) => (typeof target === "object" || typeof target === "function") && target !== null;
    
            function deepClone(target, map = new WeakMap()) {
                if (map.get(target)) {
                    return target;
                }
                // 获取当前值的构造函数:获取它的类型
                let constructor = target.constructor;
                // 检测当前对象target是否与正则、日期格式对象匹配
                if (/^(RegExp|Date)$/i.test(constructor.name)) {
                    // 创建一个新的特殊对象(正则类/日期类)的实例
                    return new constructor(target);
                }
                if (isObject(target)) {
                    map.set(target, true);  // 为循环引用的对象做标记
                    const cloneTarget = Array.isArray(target) ? [] : {};
                    for (let prop in target) {
                        if (target.hasOwnProperty(prop)) {
                            cloneTarget[prop] = deepClone(target[prop], map);
                        }
                    }
                    return cloneTarget;
                } else {
                    return target;
                }
            }
        </script>
    </body>
    
    </html>
    

    相关文章

      网友评论

          本文标题:js深拷贝和浅拷贝

          本文链接:https://www.haomeiwen.com/subject/ykxqnltx.html