• javaScript 深层复制


    在工作中遇到了深浅复制的问题,所以详细总结一下:

    深复制和浅复制只针对像 Object, Array 这样的复杂对象的。简单来说,浅复制只复制一层对象的属性,而深复制则递归复制了所有层级。

    var obj = { a:1, arr: [2,3] };
    var shadowObj = shadowCopy(obj);
    
    function shadowCopy(src) {
      var dst = {};
      for (var prop in src) {
        if (src.hasOwnProperty(prop)) {
          dst[prop] = src[prop];
        }
      }
      return dst;
    }

    这是一种典型的浅复制,shadowCopy方法将对象的各个属性进行依次复制,并不会进行递归复制,而 JavaScript 存储对象都是存地址的,所以浅复制会导致 obj.arr 和 shadowObj.arr 指向同一块内存地址。当其中一个变量对指向的值做了修改,另一个变量在调用时数值也就修改了。

    shadowObj.arr[1] = 5;
    obj.arr[1]   // = 5

    下面给出深复制的代码:

    function deepCopy ( obj ) {
             var tmp = {};  
             for ( var k in obj ) {
                tmp[ k ] = obj[ k ]; 
             }
             return tmp;
        }
        //在这个函数中最关键的一步 tmp[ k ] = obj[ k ]
        //所以这里只需要保证 obj[ k ] 这个赋值是一个深度拷贝的对象即可.
        //注意: 函数的目的是得到 obj 的深拷贝副本. 因此递归一下.
    
        function deepCopy ( obj ) {
            var tmp = {}, k;
                for ( k in obj ) {
                    if ( typeof obj[ k ] === 'object' ) {
                        tmp[ k ] = deepCopy( obj[ k ] );
                    } else {
                        tmp[ k ] = obj[ k ];
                    }
                }
                return tmp;
            }
    
            // 如果处理这个对象
            var o3 = {
                name: 'jim',
                scores: [
                    90, 
                    95,
                    85
                ]
            };
    
            // 该代码无法处理数组的情况,做如下改动
            function deepCopy ( obj ) {
                var tmp = obj.length >= 0 ? 
                            obj instanceof Array ? [] : { length: 0 } : 
                            {}, 
                    k;
                for ( k in obj ) {
                    if ( typeof obj[ k ] === 'object' ) {
                        tmp[ k ] = deepCopy( obj[ k ] );
                    } else {
                        tmp[ k ] = obj[ k ];
                    }
                }
                return tmp;
            }

    对于深复制,如果对象比较大,层级也比较多,深复制会带来性能上的问题。在遇到需要采用深复制的场景时,可以考虑有没有其他替代的方案。在实际的应用场景中,也是浅复制更为常用。

    JSON.parse( JSON.stringify(a) )这种方法比较简单,但同时也存在问题

    • 无法复制函数
    • 原型链没了,对象就是object,所属的类没了。这会抛弃对象的constructor,也就是深复制之后,无论这个对象原本的构造函数是什么,在深复制之后都会变成Object。另外诸如RegExp对象是无法通过这种方式深复制的。
    ======================================= END ========================================
  • 相关阅读:
    NOIp199Cantor表
    NOIP2001数的计算
    NOIP2010排队接水
    普及组2006第三题jam的计数法
    2013提高组积木大赛
    洛谷1223排队接水
    9.3noip模拟赛第一题卡片
    2002普及组第四题过河卒
    细胞分裂(NOIP2009 普及组第三题)
    道路游戏(NOIP2009 普及组第四题)
  • 原文地址:https://www.cnblogs.com/zhangceblogs/p/6854549.html
Copyright © 2020-2023  润新知