JS(深克隆和浅克隆)

1 区别
  浅克隆是复制对象的指针地址,而不是对象本身,新旧对象共享同一块内存。
  深克隆是另外创造一个一模一样的对象,新旧对象不再共享内存,修改新对象不会改到原对象。

2-1 浅克隆

  var liming = {
            name: "dongdong",
            age: 19,
            addresd: {
                city: "广州",
                area: "越秀区"
            }
        }
        function cloned(obj) {
            var newObj = {};
            for (var key in obj) {
                newObj[key] = obj[key];
            }
            return newObj
        }
        var liming2 = cloned(liming);
        // 因原数据的第一层数据为基本数据类型,改变 liming2.name中的值时,不会使liming对象中的原数据一同改变
        liming2.name = "koby";
        // 因原数据中包含子对象,改变liming2.addresd.area中的值时,会使liming对象中的原数据一同改变
        liming2.addresd.area = "荔湾区";
        console.log('liming', liming.name);//liming dongdong
        console.log('liming2', liming2.name);//liming2 koby
        console.log('liming', liming.addresd.area);//liming 荔湾区
        console.log('liming2', liming2.addresd.area);//liming2 荔湾区

2-2 深克隆

//Object.assign() 方法
        // 当object只有一层的时候,是深拷贝
        let obj1 = {
            username: 'lili'
        };
        let obj2 = Object.assign({}, obj1);
        obj2.username = 'yiyi';
        console.log(obj1);
        console.log(obj2);

        //  当object有两层的时候,是浅拷贝
        var obj3 = {
            city: "usa",
            a: { name: "kobe", age: 35 }
        };
        var initalObj = Object.assign({}, obj3);
        initalObj.city = "china";
        initalObj.a.age = "40";
        console.log('obj3', obj3);
        console.log('initalObj', initalObj)

//JSON方法实现深克隆
 var obj3 = {
            name: "liming",
            age: 19,
            score: null,
            addresd: {
                city: "广州",
                area: "越秀区"
            },
            friends: ["小华", "小米"]
        }
         let newObj = JSON.stringify(obj3);
         let result = JSON.parse(newObj);
         console.log(newObj);
         console.log(result);

2-3 手写实现深克隆

 // 手写深克隆函数
        var obj1 = {
            name: "liming",
            age: 19,
            score: null,
            addresd: {
                city: "欢乐世界",
                area: "番禺区"
            },
            friends: ["小莉", "小米"]
        }

        function cloned(obj) {
            if (obj === null) {
                return null   //传进来的obj就是第二次函数cloned(obj[key])调用时的obj[key]
            }
            if (Object.prototype.toString.call(obj) === "[object Array]") {
                var newArray = [];
                newArray = obj.slice();
                return newArray   
            }
            var newObj = {};
            for (var key in obj) {
                // 如原对象中当前属性为原始类型
                if (typeof obj[key] !== "object") {
                    newObj[key] = obj[key];
                }
                // 如原对象当前属性为引用类型
                else {
                    newObj[key] = cloned(obj[key]);
                }
            }
            return newObj
        }
        var obj2 = cloned(obj1);
        obj2.addresd.area = '黄浦区';
        console.log('obj1', obj1);
        console.log('obj2', obj2);
  • 总结
      * 浅克隆中如果包含内置的对象或者数组,则不再进行复制副本
  • 实现克隆的方法
      * 使用for in 遍历
      * Object.assign() 方法
      * JSON方法
      * 递归方法
posted @ 2021-01-13 22:41  简单的事情重复做  阅读(175)  评论(0)    收藏  举报