• 深拷贝和浅拷贝的区别


    作者:Mike丶

    https://www.cnblogs.com/mikeCao/p/8710837.html

    深拷贝和浅拷贝最根本的区别在于是否真正获取一个对象的复制实体,而不是引用。

    假设B复制了A,修改A的时候,看B是否发生变化:

    如果B跟着也变了,说明是浅拷贝,拿人手短!(修改堆内存中的同一个值)

    如果B没有改变,说明是深拷贝,自食其力!(修改堆内存中的不同的值)

    浅拷贝(shallowCopy)只是增加了一个指针指向已存在的内存地址,

    深拷贝(deepCopy)是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存,

    使用深拷贝的情况下,释放内存的时候不会因为出现浅拷贝时释放同一个内存的错误。

    浅复制:仅仅是指向被复制的内存地址,如果原地址发生改变,那么浅复制出来的对象也会相应的改变。

    深复制:在计算机中开辟一块新的内存地址用于存放复制的对象。

    浅拷贝实例:

    //此递归方法不包含数组对象
    var obj = { a:1, arr: [2,3] };
    var shallowObj = shallowCopy(obj);

    function shallowCopy(src) {
    var newobj = {};
    for (var prop in src) {
    if (src.hasOwnProperty(prop)) {
    newobj[prop] = src[prop];
    }
    }
    return newobj;
    }

    因为浅复制只会将对象的各个属性进行复制,并不会进行递归复制,而JavaScript存储对象是存地址的,所以浅复制会导致Obj.arr和shallowObj.arr指向同一块内存地址:

    导致的结果就是:

    shallowObj.arr[1] = 5;
    console.log(obj.arr[1]); //5

    深拷贝实例:

    var obj = {
    a:1,
    arr: [1,2],
    nation : '中国',
    birthplaces:['北京','上海','广州']
    };
    var obj2 = {name:'杨'};
    obj2 = deepCopy(obj,obj2);
    console.log(obj2);
    //深复制,要想达到深复制就需要用递归
    function deepCopy(o, c){
    var c = c || {};
    for(var i in o){
    if(typeof o[i] === 'object'){
    if(o[i].constructor === Array){
    //这是数组
    c[i] = [];
    }else{
    //这是对象
    c[i] = {};
    }
    deepCopy(o[i], c[i]);
    }else{
    c[i] = o[i];
    }
    }
    return c;
    }
    

    而深复制则不同,它不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深复制的方法递归复制到新对象上。这就不会存在obj和shallowObj的arr属性指向同一个对象的问题。

    这样obj1和obj2分别拥有不同的内存地址,两边的值改变互不影响。

    --------------------------------------------------------------------------------------------------------------------------

    浅拷贝实现:

    var a = [1, 2, 3, 4, 5];
    var b = a;
    a[0] = 2
    console.log(a);
    console.log(b);

    //因为b浅拷贝a, ab指向同一个内存地址(堆内存中存的值)
    //b会随着a的变化而变化
    //[2, 2, 3, 4, 5]
    //[2, 2, 3, 4, 5]

    深拷贝实现:

    function deepClone(obj)
    {
    var newObj = obj instanceof Array ? []:{};
    if(typeof obj !== 'object')
    {
    return obj;
    }else{
    for(var i in obj)
    {
    newObj[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i];
    }
    }
    return newObj;
    }
    
    var a = [1, 2, 4, 6, "a", "12", [1, 2]];
    var b = deepClone(a);
    a[3] = 7;
    console.log(a);
    console.log(b);
    

    //b对象并没有因为a对象的改变而改变,因为b深拷贝a
    [ 1, 2, 4, 7, 'a', '12', [ 1, 2 ] ]
    [ 1, 2, 4, 6, 'a', '12', [ 1, 2 ] ]

     

  • 相关阅读:
    什么是函数式编程
    红包算法
    laravel中查看执行的SQL语句
    身份证号信息后台匹配
    在函数内部访问外部的变量
    设计模式-观察者模式
    laravel查询构造器操作数据库
    linux根目录文件夹的作用
    关于laravel连接数据库报错
    设定起始日期,遍历到今天的日期
  • 原文地址:https://www.cnblogs.com/williamjie/p/11192895.html
Copyright © 2020-2023  润新知