zoukankan      html  css  js  c++  java
  • 深拷贝&浅拷贝

    一、什么是深拷贝&浅拷贝?

    浅复制:

    对于字符串类型,浅复制是对值的复制

    对于对象来讲,浅复制是对对象地址的复制,并没有开辟新的栈,复制的结果是两个对象 指向 同一个地址 ,此时修改 一个属性的值,另一个对象的属性也会发生变化

    深复制

    对于对象来讲,深复制是开辟新的栈,两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性 

    二、浅拷贝的实现 

    1、只复制第一层的浅拷贝

    function simpleCopy(obj1) {
       var obj2 = Array.isArray(obj1) ? [] : {};
       for (let i in obj1) {
       obj2[i] = obj1[i];
      }
       return obj2;
    }
    var obj1 = {
       a: 1,
       b: 2,
       c: {
       d: 3
      }
    }
    var obj2 = simpleCopy(obj1);
    obj2.a = 3;
    obj2.c.d = 4;
    alert(obj1.a); // 1
    alert(obj2.a); // 3
    alert(obj1.c.d); // 4
    alert(obj2.c.d); // 4

    2、Object.assign()实现浅拷贝

    let obj1 = {
       a: {
         b: 1
       },
       c: 2
    }
    let obj2 = Object.assign({},obj1)
    obj1.a.b = 3;
    obj2.c = 3
    console.log(obj1.a.b); // 3 console.log(obj2.a.b); // 3
    console.log(obj1.c); // 2 console.log(obj2.c); // 3

    三、深拷贝的实现

     1、JS实现深拷贝

    let obj1 = {
       a: 1,
       b: 2
    }
    let obj2 = {
       a: obj1.a,
       b: obj1.b
    }
    obj2.a = 3;
    alert(obj1.a); // 1
    alert(obj2.a); // 3

    2、for-in实现深拷贝

    function deepClone(obj1) {
            var obj2 = Array.isArray(obj1) ? [] : {};
    
            if (obj1 && typeof obj1 === "object") {
    
                for (var i in obj1) {
    
                    var prop = obj1[i]; // 避免相互引用造成死循环,如obj1.a=obj
    
                    if (prop == obj1) {
                        continue;
                    }
    
                    if (obj1.hasOwnProperty(i)) {
    
                        // 如果子属性为引用数据类型,递归复制
                        if (prop && typeof prop === "object") {
                            obj2[i] = (prop.constructor === Array) ? [] : {};
                            arguments.callee(prop, obj2[i]); // 递归调用
                        } else {
    
                            // 如果是基本数据类型,只是简单的复制
                            obj2[i] = prop;
                        }
                    }
                }
            }
            return obj2;
        }
    
        let obj1={a:2,b:2};
        let obj2=deepClone(obj1);
        console.log(obj1);//{a: 2, b: 2}
        console.log(obj2);//{a: 2, b: 2}
    
        obj1.a=5;
        console.log(obj1);//{a: 5, b: 2}
        console.log(obj2);//{a: 2, b: 2}

    3、使用JSON.stringify和JSON.parse实现深拷贝

    JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象;

    let deepClone=function(obj){
            let _tmp=JSON.stringify(obj);
            let result=JSON.parse(_tmp);
            return result;
        };
        let obj1={a:2,b:2};
        let obj2=deepClone(obj1);
        obj1.a=5;
        console.log(obj1);//{a: 5, b: 2}
        console.log(obj2);//{a: 2, b: 2}

    缺陷:它会抛弃对象的constructor,深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object;这种方法能正确处理的对象只有 Number, String, Boolean, Array, 扁平对象,也就是说,只有可以转成JSON格式的对象才可以这样用,像function没办法转成JSON;

    4、jQuery实现深拷贝
    
    
    //引入jquery 
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
     var myTest = {
                 a: 'a',
                 b: 'b'
     };
     var myTest2 = jQuery.extend(true,{}, myTest);
     myTest.b = 'b2';
     console.log(myTest2.b === 'b2');//false
    参考链接:https://www.jianshu.com/p/cf1e9d7e94fb
  • 相关阅读:
    Linux内核源码分析方法
    OVS处理upcall流程分析
    Linux内核源码目录结构分析
    理解OpenStack中的OpenvSwitch的几个要点
    OVS源码connmgr_run分析
    ovs-appctl 命令合集
    云计算底层技术-使用openvswitch
    OVS架构
    Open vSwitch Datapath浅析
    Openvswitch原理与代码分析(4):网络包的处理过程
  • 原文地址:https://www.cnblogs.com/qing-5/p/11356440.html
Copyright © 2011-2022 走看看