zoukankan      html  css  js  c++  java
  • js浅度克隆/深度克隆

    首先弄明白几个概念:

    一. 具体数据类型分为两种: 
        1.原始数据类型 
        2.引用数据类型

        原始数据类型存储的是对象的实际地址,包括:

        number、string、boolean、还有两个特殊的null、undefined

        引用数据类型其中存储的是对象的引用地址, 包括:. 
        array、function、object

    二. 浅度克隆:

      原始类型为值传递,对象类型仍为引用传递; 也就是说对象类型克隆的是引用地址,引用地址指向的是同一个数据空间,

      这时候改变克隆出来的数据,被克隆的数据也会变化,因为引用对象是一样的,所以数据也是一样的,改变新对象的时候 原数据也受影响。

    三. 深度克隆:

      所有元素或属性均完全复制,与原对象完全脱离,也就是说所有对于新对象的修改都不会反映到原对象中。

    具体看如下代码:

            var a = 1;
            var b = a;
            a = 10;
            console.log(b); console.log(a);// 1,10
    
            var a = 'hello';
            var b = a;
            a = 'world';
            console.log(b); console.log(a);// hello,world
    
            var a = true;
            var b = a;
            a = false;
            console.log(b); console.log(a);// true,false    

    这些都是元数据类型,克隆出来的数据跟原数据是没有关系了,新数据的改变不会影响原数据。

    看下面的代码:

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

    b 是 a 的克隆对象, [0,1,2,3]是数组,属于引用数据类型,所以 a 存储的是这个数组的引用地址。b 浅克隆 a ,所以 b 跟 a 是同一个引用地址,这样对 b 的操作 也会影响 原数据。

    解决这种问题的方法便是 使用深度克隆:

     function clone(obj){
            var buf;
            if(obj instanceof Array){
                buf = [];
                var i = obj.length;
                while(i--){
                    buf[i] = clone(obj[i]);
                }
                return buf;
            }
            else if(obj instanceof Object){
                buf = {};
                for(var k in obj){
                    buf[k] = clone(obj[k]);
                }
                return buf;
            }
            else{
                return obj;
            }
        }

    更简洁的写法如下:

    function clone(obj) {
      var o = obj instanceof Array ? [] : {};
      for(var k in obj) 
        o[k] = typeof obj[k] === Object ? clone(obj[k]) : obj[k];
      return o;
    }
    
    var a = [[1, 2, 3], [4, 5, 6, 7]];
    var b = clone(a);
    console.log(b);

    在平时的开发中,我一般都使用    JSON.parse(JSON.stringify( obj )) ;  

    但是这种方法有个问题,比如

    var a={'a':function(){},"b":111,"c":undefined}

    var b=JSON.parse(JSON.stringify(a));

    console.log(b);// {b: 111}

    就是说 会过滤掉value值 是function  undefine 的属性,使用的时候需要注意。

  • 相关阅读:
    有点忙啊
    什么是协程
    HDU 1110 Equipment Box (判断一个大矩形里面能不能放小矩形)
    HDU 1155 Bungee Jumping(物理题,动能公式,弹性势能公式,重力势能公式)
    HDU 1210 Eddy's 洗牌问题(找规律,数学)
    HDU1214 圆桌会议(找规律,数学)
    HDU1215 七夕节(模拟 数学)
    HDU 1216 Assistance Required(暴力打表)
    HDU 1220 Cube(数学,找规律)
    HDU 1221 Rectangle and Circle(判断圆和矩形是不是相交)
  • 原文地址:https://www.cnblogs.com/yalong/p/9406068.html
Copyright © 2011-2022 走看看