zoukankan      html  css  js  c++  java
  • JS学习笔记——浅拷贝和深拷贝

    1.浅拷贝与深拷贝

    浅拷贝是指,在复制变量时,对于引用类型的变量,只拷贝其引用,不拷贝其在堆中的真实数据。深拷贝是指,拷贝堆中的数据,一个新的引用指向新拷贝出来的数据。

    2.Array的push方法是浅拷贝

    判断浅拷贝还是深拷贝,一个很简单的方法就是使用全等(===),当两个对象进行比较时,只有指向同一个对象,结果才会是true。当向arr中push一个obj,全等的结果是true,说明两个引用指向的是同一个对象,arr中保存的是旧引用而不是新引用。当我们修改obj后,arr也会一起被修改。当对obj赋值null,由于obj不再是引用,而arr中还保存有引用,所以他们不相等。
    我原本以为执行obj=null之后,arr中保存的对象也会没掉,其实并不是。obj是引用,让其等于null只是改变obj的指向,并不影响堆中的真实对象。由于堆中的真实对象还有arr对其引用,所以该对象不会被垃圾回收。

    var arr =[];
    var obj = {name:'abc',obj:{name:'new'}};
    arr.push(obj);
    
    console.log(arr[0] === obj);//true
    console.log(JSON.stringify(arr[0]));
    console.log(JSON.stringify(obj));
    
    obj.name = '123';
    console.log(arr[0] === obj);//true
    console.log(JSON.stringify(arr[0]));
    console.log(JSON.stringify(obj));
    
    obj = null;
    console.log(arr[0] === obj);//false
    console.log(JSON.stringify(arr[0]));
    console.log(JSON.stringify(obj));
    

    3.对象的深拷贝

    对象深拷贝的方法就是遍历对象的属性,并把属性赋值给新对象。数组是比较特殊的对象,在拷贝数组的时候,需要初始化的是[]

    function deep(src) {
         var des = Array.isArray(src) ? [] : {};
         for(var key in src) {
            if(src.hasOwnProperty(key)) {
                des[key] = src[key];
            }
         }
         return des;
    }
    var des = deep(src);
    

    上面这个拷贝方法会有一些问题:当对象的属性还是对象的时候,该属性对象会是浅拷贝。对于这种情况,我们可以递归地调用该方法。

    function deep(src) {
         var des = Array.isArray(src) ? [] : {};
         for(var key in src) {
            if(src.hasOwnProperty(key)) {
                des[key] = (typeof src[key] == 'object') ? deep(src[key]) : src[key];
            }
         }
         return des;
    }
    var des = deep(src);
    

    JQuery中的浅、深拷贝。第一个参数代表是否深拷贝,第二个参数是目的对象,第三个参数是要拷贝的源对象。

    %.extend({}, src);//浅拷贝
    %.extend(true, {}, src);//深拷贝
    

    上面给出的深拷贝代码解决了嵌套对象的问题,但如果属性是函数的话,该属性是浅拷贝,是对函数的引用。

  • 相关阅读:
    eclipse中svn的各种状态图标详解
    Invalid configuation file. File "**********" was created by a VMware product with more feature than this version of VMware Workstation and cannot be
    linux下tomcat无法访问问题(换一种说法:无法访问8080端口)
    安装MySQL start Service(无法启动服务)
    eclipse下SVN subclipse插件
    tomcat启动窗口中的时间与系统时间不一致
    关于如果从SQLSERVER中获取 数据库信息 或者 表信息
    有关google的appengine部署服务器的简单教程
    部署到Google App Engine时中途退出后引起的问题
    重温WCF之数据契约中使用枚举(转载)(十一)
  • 原文地址:https://www.cnblogs.com/season-peng/p/6771587.html
Copyright © 2011-2022 走看看