zoukankan      html  css  js  c++  java
  • js 深拷贝和浅拷贝实现

    浅拷贝

    //用=赋值
    var a = {name:'hello'};
    var b = a;
    b.name="world";
    console.log(a.name);
    
    
    // 只复制第一层的浅拷贝
    function simpleCopy(obj1) {
       var obj2 = Array.isArray(obj1) ? [] : {};
       for (let i in obj1) {
       obj2[i] = obj1[i];
      }
       return obj2;
    }
    var obj1 = {
       a: 1,
       b: 2,
       c: {
             d: 3
          }
    }
    var obj2 = simpleCopy(obj1);
    obj2.a = 3;
    obj2.c.d = 4;
    alert(obj1.a); // 1
    alert(obj2.a); // 3
    alert(obj1.c.d); // 4
    alert(obj2.c.d); // 4
    
    //Object.assign()
    var obj = {
        a: 1,
        b: 2
    }
    var obj1 = Object.assign(obj);
    obj1.a = 3;
    console.log(obj.a) // 3
    

    深拷贝

    //递归拷贝
    function deepClone(obj){
        let objClone = Array.isArray(obj)?[]:{};
        if(obj && typeof obj==="object"){
            for(key in obj){
                if(obj.hasOwnProperty(key)){
                    //判断ojb子元素是否为对象,如果是,递归复制
                    if(obj[key]&&typeof obj[key] ==="object"){
                        objClone[key] = deepClone(obj[key]);
                    }else{
                        //如果不是,简单复制
                        objClone[key] = obj[key];
                    }
                }
            }
        }
        return objClone;
    }    
    let a=[1,2,3,4],
        b=deepClone(a);
    a[0]=2;
    console.log(a,b);
    
    //JSON
    var _obj = JSON.stringify(obj),
    objClone = JSON.parse(_obj);
    
    //lodash cloneDeep
    let result = _.cloneDeep(test)
    
    //jquery extend
    var array = [1,2,3,4];
    var newArray = $.extend(true,[],array); // true为深拷贝,false为浅拷贝
    
    let obj1 = {
       a: 1,
       b: 2
    }
    let obj2 = {
       a: obj1.a,
       b: obj1.b
    }
    obj2.a = 3;
    alert(obj1.a); // 1
    alert(obj2.a); // 3
    
    //直接使用var newObj = Object.create(oldObj),可以达到深拷贝的效果。
    function deepClone(initalObj, finalObj) {    
      var obj = finalObj || {};    
      for (var i in initalObj) {        
        var prop = initalObj[i];        // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
        if(prop === obj) {            
          continue;
        }        
        if (typeof prop === 'object') {
          obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
        } else {
          obj[i] = prop;
        }
      }    
      return obj;
    }
    
    //拓展运算符
    // 当value是基本数据类型,比如String,Number,Boolean时,是可以使用拓展运算符进行深拷贝的
    // 当value是引用类型的值,比如Object,Array,引用类型进行深拷贝也只是拷贝了引用地址,所以属于浅拷贝
    var car = {brand: "BMW", price: "380000", length: "5米"}
    var car1 = { ...car, price: "500000" }
    console.log(car1); // { brand: "BMW", price: "500000", length: "5米" }
    console.log(car); // { brand: "BMW", price: "380000", length: "5米" }
    
    //concat()
    // 当数组里面的值是基本数据类型,比如String,Number,Boolean时,属于深拷贝
    var arr1 = ["1","2","3"];
    var arr2 = arr1.concat();
    arr2[1] = "9";
    console.log("数组的原始值:" + arr1 );
    console.log("数组的新值:" + arr2 );
    // 当数组里面的值是引用数据类型,比如Object,Array时,属于浅拷贝
    var arr1 = [{a:1},{b:2},{c:3}];
    var arr2 = arr1.concat();
    arr2[0].a = "9";
    console.log("数组的原始值:" + arr1[0].a ); // 数组的原始值:9
    console.log("数组的新值:" + arr2[0].a ); // 数组的新值:9
    
    //slice()
    // 当数组里面的值是基本数据类型,比如String,Number,Boolean时,属于深拷贝
    // 当数组里面的值是引用数据类型,比如Object,Array时,属于浅拷贝
    var arr1 = ["1","2","3"]; 
    var arr2 = arr1.slice(0);
    arr2[1] = "9";
    console.log("数组的原始值:" + arr1 );
    console.log("数组的新值:" + arr2 );
    
    //如果对象的value是基本类型的话,也可以用Object.assign来实现深拷贝,但是要把它赋值给一个空对象
    var obj = {
        a: 1,
        b: 2
    }
    var obj1 = Object.assign({}, obj); // obj赋值给一个空{}
    obj1.a = 3;
    console.log(obj.a);// 1
    
  • 相关阅读:
    响应式面包屑菜单
    自定义美化UL OL发光列表
    3D立方体图片切换动画
    超酷Loading进度条
    比特币网络的弱点(二)
    比特币网络的弱点
    C++的价值
    《老罗的Android之旅》导读PPT
    系统的思考性能问题
    no_expand优化案例
  • 原文地址:https://www.cnblogs.com/-swz/p/14278515.html
Copyright © 2011-2022 走看看