ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

对象、数组、函数等多种数据类型的深浅克隆(拷贝)

2022-03-28 13:02:42  阅读:165  来源: 互联网

标签:10 obj3 obj2 obj log 数据类型 console 拷贝 克隆


对象(数组)的深浅克隆

浅克隆

obj{ }对象里面的所有属性拷贝到obj1{ }中后,然后分别改变对象里面的变量,原始值互不影响,引用值一个改变,另一个跟着变。

<!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>Document</title>
</head>
<body>
    <script>
        // 浅克隆
        // a、d 原始值; b、c 引用值
        let obj = {
            a: 100,
            b: [10, 20, 30],
            c: {
                x: 10
            },
            d: /^\d+$/
        };

        // let obj2 = {...obj};

        let obj2 = {};
        for (let key in obj) {
            if (!obj.hasOwnProperty(key)) break;
            obj2[key] = obj[key];
        }
        console.log(obj);   //  { a: 100, b: (3) [10, 20, 30], c: {x: 10}, d: /^\d+$/ }
        console.log(obj2);  //  { a: 100, b: (3) [10, 20, 30], c: {x: 10}, d: /^\d+$/ }

        obj2.a = 200;
        obj2.b[0] = 55;
        obj2.c["x"] = 66;
        obj2.d = /^\d-$/;

        console.log(obj);   //  { a: 100, b: (3) [55, 20, 30], c: {x: 66}, d: /^\d+$/ }
        console.log(obj2);  //  { a: 200, b: (3) [55, 20, 30], c: {x: 66}, d: /^\d-$/ }
    </script>
</body>
</html>

深克隆

修改引用值时,互不影响,你改我不变

<!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>Document</title>
</head>
<body>
    <script>
        // 深克隆
        let obj = {
            a: 100,
            b: [10, 20, 30],
            c: {
                x: 10
            },
            d: /^\d+$/,
            e : function() {
                return 50;
            },
            f: new Date(),
            g: new Map([["a", 1], ["b", 2], ["c", 3]]),
            h: new Set([1, 2, 3, 3, 4, {a : 10}]),
            i: null,
            j: undefined
        };

        // 先转为字符串再转回对象的过程会重新开辟内存空间
        //  日期,函数,正则在转为字符串时会出现问题
        // 函数(不输出),正则(输出空对象),时间对象(输出时间字符串),Undefiend(不输出)
        let obj2 = JSON.parse(JSON.stringify(obj));  
        obj2.b[0] = 22;
        console.log(obj);   //  { a: 100, b: (3) [10, 20, 30], c: {x: 10}, d: /^\d+$/, e: ƒ e() }
        console.log(obj2);  //  { a: 100, b: (3) [22, 20, 30], c: {x: 10}, d: {}, [[Prototype]]: Object }

        function deepClone(obj) {
            // 处理null
            if (obj === null) return null;
            // 处理原始值
            if (typeof obj  != "object" && typeof obj != "function") return obj;
            // 处理函数
            if (typeof obj === "function") {
                let func = obj + ''
                // 返回匿名函数
                // new Function('...')()  直接执行引号中的内容,与eval
                return new Function('return ' + func)();
            }
            // 处理正则
            if (obj instanceof RegExp) {
                return new RegExp(obj);
            }
            // 处理Set对象
            if (obj instanceof Set) {
                return new Set(obj);
            }
            // 处理Map对象
            if (obj instanceof Map) {
                return new Map(obj);
            }
            // 处理日期
            if (obj instanceof Date) {
                return new Date(obj);
            }
            // 用被克隆对象的构造函数创建一个实例,这样克隆出来的对象也是那个构造函数的实例,保持相同的所属类
            let newObj = new obj.constructor;
            for (let key in obj) {
                if (obj.hasOwnProperty(key)) {
                    newObj[key] = deepClone(obj[key]);
                }
            }

            return newObj;
        }
        let obj3 = deepClone(obj);
        console.log(obj);   //  { a: 100, b: (3) [10, 20, 30], c: {x: 10}, d: /^\d+$/, e: ƒ e() }
        console.log(obj3);  //  { a: 100, b: (3) [10, 20, 30], c: {x: 10}, d: /^\d+$/, e: ƒ e() }
        console.log(obj === obj3);      //  false
        console.log(obj.c === obj3.a);  //  false
        console.log(obj.e === obj3.b);  //  false
        console.log(obj.e === obj3.c);  //  false
        console.log(obj.e === obj3.d);  //  false
        console.log(obj.e === obj3.e);  //  false
        console.log(obj.e === obj3.f);  //  false
        console.log(obj.e === obj3.g);  //  false
        console.log(obj.e === obj3.h);  //  false
        console.log(obj.e === obj3.i);  //  false
        console.log(obj.e === obj3.j);  //  false
    </script>
</body>
</html>

标签:10,obj3,obj2,obj,log,数据类型,console,拷贝,克隆
来源: https://www.cnblogs.com/by0627/p/16066576.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有