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 的属性,使用的时候需要注意。

  • 相关阅读:
    小程序工程化探索:大规模场景下的问题和解决方案----------------引用
    对Taro Next小程序跨框架开发的探索与实践-----------------引用
    对Node.js 中的依赖管理------------引用
    对redux的研究--------引用
    JavaScript 中的 for 循环---------------引用
    对JavaScript 模块化的深入-----------------引用
    对Webpack 应用的研究-----------------引用
    webpack5持久化缓存
    设置x 轴斜体(每次我都百度,这次单独为它发一个)
    字典元组列表常用方法
  • 原文地址:https://www.cnblogs.com/yalong/p/9406068.html
Copyright © 2011-2022 走看看