javascript中的深复制和浅复制

原创 2018年04月17日 21:22:29
链接:https://www.zhihu.com/question/23031215/answer/46220227


首先深复制和浅复制只针对像 Object, Array 这样的复杂对象的。简单来说,浅复制只复制一层对象的属性,而深复制则递归复制了所有层级。

抛开jQuery,上代码例子。下面是一个简单的浅复制实现:

var obj = { a:1, arr: [2,3] };
var shallowObj = shallowCopy(obj);

function shallowCopy(src) {
  var dst = {};
  for (var prop in src) {
    if (src.hasOwnProperty(prop)) {
      dst[prop] = src[prop];
    }
  }
  return dst;
}

因为浅复制只会将对象的各个属性进行依次复制,并不会进行递归复制,而 JavaScript 存储对象都是存地址的,所以浅复制会导致 obj.arr 和 shallowObj.arr 指向同一块内存地址,大概的示意图如下。



导致的结果就是:

shallowObj.arr[1] = 5;
obj.arr[1]   // = 5

而深复制则不同,它不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深复制的方法递归复制到新对象上。这就不会存在上面 obj 和 shallowObj 的 arr 属性指向同一个对象的问题。

var obj = { a:1, arr: [1,2] };
var obj2 = deepCopy(obj);

结果如下面的示意图所示:



需要注意的是,如果对象比较大,层级也比较多,深复制会带来性能上的问题。在遇到需要采用深复制的场景时,可以考虑有没有其他替代的方案。在实际的应用场景中,也是浅复制更为常用。

深复制的几种实现方法:

1.利用递归实现

function deepCopy(o,c){    //利用递归深复制
    var c = c || {};
    for(var i in o){
        if(typeof o[i] === 'object'){
            //要考虑深复制问题了
            if(o[i].constructor === Array){
                //这是数组
                c[i] =[];
            }else{
                //这是对象
                c[i] = {};
            }
            deepCopy(o[i],c[i]);
        }else{
            c[i] = o[i];
        }
    }
    return c;
}
2.另一种递归
var cloneObj = function(obj){
    var str, newobj = obj.constructor === Array ? [] : {};
    if(typeof obj !== 'object'){
        return;
    } else if(window.JSON){
        str = JSON.stringify(obj); //系列化对象
            newobj = JSON.parse(str); //还原
    } else {
        for(var i in obj){
            newobj[i] = typeof obj[i] === 'object' ? cloneObj(obj[i]) : obj[i];
        }
    }
    return newobj;
};

3.通过JSON解析解决(还没用过)

var test ={
	  	name:{
	  	 xing:{ 
	  	     first:'张',
	  	     second:'李'
	  	},
	  	ming:'老头'
	  },
	  age :40,
	  friend :['隔壁老王','宋经纪','同事']
	 }
	  var result = JSON.parse(JSON.stringify(test))
	  result.age = 30
	  result.name.xing.first = '往'
	  result.friend.push('fdagldf;ghad')
	  console.dir(test)
	  console.dir(result)

python深复制与浅复制

在python中尽量不要使用全局变量更不能随便修改全局变量的值,也不能随便修改可变数 据类型的值, 否则会引发不易发现的异常,在进行变量复制时要分清是浅复制还是深复制,变量名内存放的是地址, 把...
  • qi1840439776
  • qi1840439776
  • 2017-03-16 20:44:25
  • 203

ES6(JavaScript)的深复制和浅复制

React中,我们会遇到一个有趣的问题,那就是对象的复制,为什么说有趣,是因为直觉和结果差距很大。 我们看一下这个例子: let a={tile:'深复制'}; let b=a; a.title=...
  • wwlxz22
  • wwlxz22
  • 2017-12-06 20:36:03
  • 433

C++深复制和浅复制

对象的复制;复制构造函数;浅复制和深复制;再一个深复制的例子
  • sxhelijian
  • sxhelijian
  • 2014-04-09 10:22:30
  • 11207

类对象的浅拷贝和深拷贝(浅复制和深复制)

浅拷贝(浅复制)        在C++中经常隐式或显式的出现对象的复制。当两个对象之间进行复制时,若复制完成后,它们还共享某些资源(内存空间),其中一个对象的销毁会影响另一对象,这种对象之间的复制...
  • liuxiao2030
  • liuxiao2030
  • 2016-12-20 10:53:00
  • 282

js 深复制(深拷贝)和浅复制(浅拷贝)的区别

最近在做项目的时候,发现deepCopy()这个函数,顾名思义是深复制的意思,有了深复制反向思考肯定有浅复制,查阅资料之后便做下整理~ 个人理解,深复制和浅复制最根本的区别在于**是否是真正获...
  • sjn0503
  • sjn0503
  • 2016-08-21 15:06:55
  • 3065

java深复制和浅复制的区别

转自:http://blog.csdn.net/tkd03072010/article/details/6730513 首先我们看看浅拷贝和深拷贝的定义     浅拷贝:只复制一个对象...
  • lalioCAT
  • lalioCAT
  • 2016-03-14 16:48:26
  • 950

关于iOS中objc深复制与浅复制你该知道的

什么是浅复制(浅拷贝)与深复制(深拷贝)? 浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用变量不同,即名称不同。对某中任何一个对象的改动都会影响另一个对象。 深拷贝是指源对象与拷贝对象互相独立,其...
  • ruglcc
  • ruglcc
  • 2017-03-29 15:22:28
  • 699

Java中clone方法以及深复制和浅复制

Java中处理基本数据类型(如:int , char , double等),都是采用按值传递的方式执行,除此之外的其他类型都是按照引用传递(传递的是一个对象的引用)的方式执行。对象在函数调用时和使用“...
  • nuisthou
  • nuisthou
  • 2016-11-13 10:13:20
  • 1310

Python中"=“,浅复制和深复制的理解

(1)赋值语句“=”的理解在Python中,对象的管理是通过对象引用计数器来实现的。如果某个对象的引用计数器变为0时,那么该实例化对象将无法再被获取,系统会自动将其消亡并回收相应的内存,这也是内存管理...
  • ailanchong
  • ailanchong
  • 2016-04-05 10:20:50
  • 191

java的深复制与浅复制

  • 2015年08月17日 16:22
  • 10KB
  • 下载
收藏助手
不良信息举报
您举报文章:javascript中的深复制和浅复制
举报原因:
原因补充:

(最多只允许输入30个字)