• JavaScript深拷贝浅拷贝全析


    浅拷贝

    用浅拷贝如果改变obj2的对象,obj1不会再改变,它们不会引用一个值,但如果对象里面还有对象,就会失效,它们是同一个引用。

    方法1:用Object.create克隆对象

    方法2:数组用concat

    方法3:对象用assign

    方法4:扩展运算符(...)

    方法1:用Object.create克隆对象

    用法:

    var obj1 = {a:2,b:{name:'小明'}};
    var obj2 = Object.create(obj1);
    
    

    详解:

    var obj1 = {a:2,b:{name:'小明'}};
    var obj2 = Object.create(obj1);
    obj2.a = 3;
    obj2.b.name = '小红';
    console.log(obj1,obj2);
    

    结果:

    image

    结论:

    obj1对象中的一级对象a:2并没有受影响,但二级对象b已经受影响。所以Object.create克隆的对象也只能实现一级对象的深拷贝

    方法2:数组用concat

    用法:

    [].concat(arr)
    

    详解:

    var arr = [{id:1,name:'1',other:{sex:'男'}}]
    var brr = [].concat(arr);
    brr[0].id = 2;
    brr[0].other.sex = '女';
    console.log(arr[0],brr[0])
    

    结果:

    image

    结论:

    arr的一级对象(id)和对象里面的对象(other.sex)都是引用同一个指针,不能实现深拷贝。

    方法3:对象用assign

    用法:

    var obj1 = {a: 1}
    var obj2 = Object.assign({}, obj1)
    

    详解:

    var obj = {id:1,name:{a:'xx'},fn:function(){},un:undefined};
    var obj2 = Object.assign({}, obj);
    obj2.id = 2;
    obj2.name.a = 'obj2';
    console.log(obj,obj2)
    

    结果:

    image

    结论:

    obj的一级对象(id)的确不受影响,但对象里面的对象(name.a)还是引用同一个指针,不能实现深拷贝。

    方法4:扩展运算符(...)

    用法:

    var obj1 = {a: 1}
    var obj2 = {...obj1}
    

    详解:

    var obj = {id:1,name:{a:'xx'},fn:function(){},un:undefined};
    var obj2 = {...obj};
    obj2.id = 2;
    obj2.name.a = 'obj2';
    console.log(obj,obj2)
    

    结果:

    image

    结论:

    obj的一级对象(id)的确不受影响,但对象里面的对象(name.a)还是引用同一个指针,不能实现深拷贝。

    深拷贝

    方法1:JSON.parse(JSON.stringify())

    方法2:MessageChannel

    方法3:lodash.cloneDeep

    用深拷贝的话,就算对象里面还有对象,也不会是同一个引用,但是会忽略undefinedfunction,用方法3不会忽略functionundefined

    方法1:JSON.parse(JSON.stringify())

    var obj1 = {a: 1}
    obj2 = JSON.parse(JSON.stringify(obj1))
    

    方法2:MessageChannel

    var obj = {id:1,name:{a:'xx'}};
    
    function structuralClone(obj) {
        return new Promise((resolve) => {
            const {port1, port2} = new MessageChannel();
            port2.onmessage = ev => resolve(ev.data);
            port1.postMessage(obj);
        })
    }
    structuralClone(obj).then(res=>{
        console.log(res);
        var obj3 = res;
        obj3.name.a = 'obj3';
        console.log(obj,obj3);
    })
    
    <!-- 用promise是为了好传数据 -->
    

    image

    方法3:lodash.cloneDeep

    import _ from 'lodash'
    var obj = {id:1,name:{a:'xx'},fn:function(){},un:undefined};
    var obj2 = _.cloneDeep(obj);
    obj2.name.a = 'obj2';
    console.log(obj,obj2)
    

    image

  • 相关阅读:
    《不完美的她》开播,网友:周公子对「白帽子」有点误会吧?
    【Web安全】浅谈缓存XSS漏洞
    十分钟教你轻松掌握「移动PE导出表」,快来学习!
    干货分享丨表哥带你学习导入表及导入表注入
    「原创」萌新也能看懂的ThinkPHP3.2.3漏洞分析
    精选好文丨简析对称加密、非对称加密和混合加密
    工程师成长道路语录(转)
    在线画UML图的工具
    6种有效的开发模型(转)
    空降经理人的挑战 (原创)
  • 原文地址:https://www.cnblogs.com/firefly-pengdan/p/13409193.html
Copyright © 2020-2023  润新知