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

    JavaScript有两种数据类型,基础数据类型和引用数据类型。基础数据类型都是按值访问的,我们可以直接操作保存在变量中的实际的值。而引用类型如Array,我们不能直接操作对象的堆内存空间。引用类型的值都是按引用访问的,即保存在变量对象中的一个地址,该地址与堆内存的实际值相关联。

    一、深拷贝和浅拷贝的区别

      浅拷贝(shallow copy):只复制指向某个对象的指针,而不复制对象本身,新旧对象共享一块内存;
      深拷贝(deep copy):复制并创建一个一摸一样的对象,不共享内存,修改新对象,旧对象保持不变。

    var a = 25;
    var b = a;
    b = 10;
    console.log(a);//25
    console.log(b);//10
    
    //浅拷贝
    var obj1 = { a: 10, b: 20, c: 30 };
    var obj2 = obj1;
    obj2.b = 40;
    console.log(obj1);// { a: 10, b: 40, c: 30 } 
    console.log(obj2);// { a: 10, b: 40, c: 30 }
    
    //深拷贝
    var obj1 = { a: 10, b: 20, c: 30 };
    var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c };
    obj2.b = 40;
    console.log(obj1);// { a: 10, b: 20, c: 30 }
    console.log(obj2);// { a: 10, b: 40, c: 30 }

    二、浅拷贝的实现

    var json1 = {"a":"name","arr1":[1,2,3]}
    function copy(obj1) {
        var obj2 = {};
        for (var i in obj1) {
          obj2[i] = obj1[i];
        }
        return obj2;
    }
    var json2 = copy(json1);
    json1.arr1.push(4);
    alert(json1.arr1);  //1234
    alert(json2.arr1)  //1234

    三、深拷贝的实现

    1、Object.assign()

    let foo = {
        a: 1,
        b: 2,
        c: {
            d: 1,
        }
    }
    let bar = {};
    Object.assign(bar, foo);
    foo.a++;
    foo.a === 2 //true
    bar.a === 1 //true
    foo.c.d++;
    foo.c.d === 2 //true
    bar.c.d === 1 //false
    bar.c.d === 2 //true

      Object.assign()是一种可以对非嵌套对象进行深拷贝的方法,如果对象中出现嵌套情况,那么其对被嵌套对象的行为就成了普通的浅拷贝。

    2、转成JSON

      用JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象。

    var obj1 = { body: { a: 10 } };
    var obj2 = JSON.parse(JSON.stringify(obj1));
    obj2.body.a = 20;
    console.log(obj1);   // { body: { a: 10 } } 
    console.log(obj2);   // { body: { a: 20 } }
    console.log(obj1 === obj2);   // false
    console.log(obj1.body === obj2.body);   // false

      但这种方法的缺陷是会破坏原型链,并且无法拷贝属性值为function的属性

    3、递归

      采用递归的方法去复制拷贝对象

    var json1={"name":"shauna","age":18,"arr1":[1,2,3,4,5],"string":'got7',"arr2":[1,2,3,4,5],"arr3":[{"name1":"shauna"},{"job":"web"}]};
    var json2={};
    function copy(obj1,obj2){
      var obj2=obj2||{};
      for(var name in obj1){
        if(typeof obj1[name] === "object"){ 
          obj2[name]= (obj1[name].constructor===Array)?[]:{}; 
          copy(obj1[name],obj2[name]); 
        }else{
          obj2[name]=obj1[name];  
        }
      }
      return obj2;
    }
    json2=copy(json1,json2)
    json1.arr1.push(6);
    alert(json1.arr1);  //123456
    alert(json2.arr1);  //12345
     
  • 相关阅读:
    Java并发编程(1)-Java内存模型
    Java源码解读(一) 8种基本类型对应的封装类型
    怎样修改织梦网站的favicon图标
    友情链接:图片链接或文字链接
    FCKeditor 添加行距、字体功能 (转载)
    如何解决织梦DedeCMS后台模块管理列表不显示
    制作兼容各种版本浏览器的新闻图片焦点切换效果
    织梦添加站内搜索
    织梦友情链接正确的调用方法和技巧
    织梦后台添加友情链接的方法(flink标签)
  • 原文地址:https://www.cnblogs.com/manshufeier/p/9612589.html
Copyright © 2011-2022 走看看