• JS的浅拷贝和深拷贝


    最近在开发中遇到一个小问题,就是由于js的浅拷贝导致变量被污染,突然发现对于js的变量值传递和引用传值并没有特别注意,如今总结如下,以备来者考虑。

    JS的变量分普通类型和引用类型,具体如下:

     基本数据类型:StringBooleanNumberUndefinedNull

     引用数据类型:Object(ArrayDateRegExpFunction)

    对于普通类型的变量赋值都是值传递,而引用类型变量的赋值。例如下面的代码:

          

            var b = 3;
    
            var c = b;
    
            b = 2;
    
            console.log(b); // 2
    
            console.log(c); // 3

    普通的数据类型变量的赋值,只是值传递,变量之间互不影响。而引用类型不同:

            

            var MyObj = {
    
                price: "200.00",
    
                count: 24
    
            };
    
            var Gift = MyObj;
    
            MyObj.price = "300.00";
    
            console.log(Gift.price);  // 300.00
    
            console.log(MyObj.price); // 300.00

    所以这种引用类型变量的复制是被称为浅拷贝:新变量的指针指向被复制的变量,当被复制的变量发生变化,新变量也会随着改变。而我们工作实际中是需要完全拷贝一个变量,一个完整备份,这就是深拷贝。

    简单来说,深浅拷贝的原理图如下:

       

    所以问题来了,怎么才能实现深拷贝的。

    两种途径,一种自己使用递归的方式去做深拷贝,一种使用第三方库或者es原生实现。

    es6的方式最简单,结合递归代码如下:

    // 递归方式实现深拷贝
    function DeepCopy(obj) {
        var return_obj = {};
    
        for (let key in obj) {
           if (Object.prototype.toString.call(obj[key]) === '[Object Object]') {
             return_obj[key] = DeepCopy(obj[key]);  
           } else {
            return_obj[key] = {...obj[key]};  // es6语法糖,处理当前层次赋值为深拷贝
           }
    
       }
       return return_obj;
    }

    第三方库可以使用loadash

    var _ = require('lodash');
    
    var obj1 = {    a: 1,    b: { f: { g: 1 } },    c: [1, 2, 3] };
    
    var obj2 = _.cloneDeep(obj1);
    
    console.log(obj1.b.f === obj2.b.f); // false
  • 相关阅读:
    bootstrap的demo网站
    百度地图和js操作iframe
    (转)关于List中FindAll用法的一些简单示例
    (转)ORACLE触发器详解
    多线程Java Socket编程示例(转)
    java Socket用法详解(转)
    java socket编程基础(转)
    Java Socket 基础例子
    C# Socket服务器端如何判断客户端断开
    windows server 2008 R2 远程连接用户数修改
  • 原文地址:https://www.cnblogs.com/freephp/p/11106496.html
Copyright © 2020-2023  润新知