深拷贝和浅拷贝

230 阅读1分钟

浅拷贝

浅拷贝(shallow copy)对对象的浅层进行复制(只复制一层)。

  • Object.assign()方法 用于浅拷贝对象。
  • 也可以用扩展运算符...完成浅拷贝。

浅拷贝原理

  • 利用for/in循环拿到属性名完成赋值。
  • 以下代码可以看出person1和person2中的first对象指向的是同一个内存地址,所以其中的name属性改变后,另一个也会改变。
        var person1 = {
            name: '张三',
            age: 18,
            sex: 'male',
            children: {
                first: {
                    name: '张三',
                    age: 18
                },
                second: {
                    name: '李四',
                    age: 19
                },
                third: {
                    name: '王五',
                    age: 20
                }
            }
        }

        function clone(origin, target){
            var tar = target || {};

            for(var key in origin){
                tar[key] = origin[key];
            }
            return tar;
        }

        var person2 = clone(person1);

        person2.age = 20;
        person2.children.first.name = '玛琪玛';
        console.log(person1.age); // 18
        console.log(person2.age); // 20
        console.log(person1.children.first.name); // '玛琪玛'
        console.log(person2.children.first.name); // '玛琪玛'

深拷贝

深拷贝(deep copy)不仅复制对象本身,还复制对象中的属性。

  • structoredClone(obj)方法 用于深拷贝对象。

深拷贝原理

  • 利用递归的方式进行循环,直到object类型全部复制完毕。
  • 目标和源引用值都是独立的,不会出现同时更改的问题。
        function deepClone(origin, target){
            var target = target || {},
                toStr = Object.prototype.toString,
                arrType = '[object Array]';
                
            for(var key in origin){
                if(origin.hasOwnProperty(key)){
                // 判断是否是obejct类型
                // null存在历史遗留问题,也是object类型,所以需要判断。
                    if(typeof(origin[key]) === 'object' && origin[key] !== null){
                        if(toStr.call(origin[key]) === arrType){
                            target[key] = [];
                        }
                        else{
                            target[key] = {};
                        }
                        deepClone(origin[key], target[key]);
                    }
                    else{
                        target[key] = origin[key];
                    }
                }
            }
            return target;
        }