javascript对象深拷贝,浅拷贝 ,支持数组

经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝。

下面是维基百科对深浅拷贝的解释:

浅拷贝

One method of copying an object is the shallow copy. In the process of shallow copying A, B will copy all of A's field values. If the field value is a memory address it copies the memory address, and if the field value is a primitive type it copies the value of the primitive type.

The disadvantage is if you modify the memory address that one of B's fields point to, you are also modifying what A's fields point to.

一种拷贝对象的方式是浅拷贝,浅拷贝对象A时,对象B将拷贝A的所有字段,如果字段是内存地址,B将拷贝地址,若果字段是基元类型,B将复制其值。

浅拷贝的缺点是如果你改变了对象B所指向的内存地址,你同时也改变了对象A指向这个地址的字段。

深拷贝

An alternative is a deep copy. Here the data is actually copied over. The result is different from the result a shallow copy gives. The advantage is that A and B do not depend on each other but at the cost of a slower and more expensive copy.

另一种是深拷贝,这种方式会完全拷贝所有数据,优点是B与A不会相互依赖(A,B完全脱离关联), 缺点是拷贝的速度更慢,代价更大 (我的理解是耗费了更多内存空间)

C#中的对象拷贝

c#中的浅拷贝

C#万恶的Object基类中定义了一个protected的浅拷贝函数MemberwiseClone ,下面是测试代码

  1. public class Address
  2. {
  3. public string ZipCode { get; set; }
  4. public string City { get; set; }
  5. }
  6.  
  7. public class Person
  8. {
  9. public string Name { get; set; }
  10. public int Age { get; set; }
  11. public Address Address { get; set; }
  12.  
  13. /// <summary>
  14. /// 暴露浅拷贝功能
  15. /// </summary>
  16. /// <returns></returns>
  17. public Person Clone()
  18. {
  19. return this.MemberwiseClone() as Person;
  20. }
  21. }
  22. class Program
  23. {
  24. static void Main(string[] args)
  25. {
  26. Person p = new Person();
  27. p.Name = "leon";
  28. p.Age = 5;
  29. p.Address = new Address
  30. {
  31. ZipCode = "200000",
  32. City = "Shanghai"
  33. };
  34.  
  35. Person copy = p.Clone();
  36.  
  37. copy.Address.City = "beijing";
  38.  
  39. Console.WriteLine(p.Address.City); // print beijing
  40.  
  41. Console.Read();
  42. }
  43. }

c#中的深拷贝

我们可以利用序列化和反序列化来轻易实现深拷贝,c#中可选的序列化方法有许多,比如BinaryFormatter, XML serializer, JSON serializer ,因为本文主要是将js的,所以不过多介绍。

javascript 也来玩玩拷贝

javascript 浅拷贝对象

这里把上面的c# person对象 翻译成一个json 对象 {name:'leon', age:5, address:{zipcode:'200000',city:'shanghai'}}

在js中, 浅拷贝非一般的简单,如下,大家可以测试测试 (为了简单,这里省去了参数的判断) :

  1. function shallowCopy( o )
  2. {
  3. var copy = {};
  4. for ( var i in o )
  5. {
  6. copy[i] = o[i];
  7. }
  8.  
  9. return copy;
  10. }

javascript 深拷贝对象

要实现js的深拷贝也很简单, 就是在浅拷贝的基础上,判断当前迭代的字段是否为非null的 object 对象,如果是,递归浅拷贝处理. 综上所述, 然后考虑了数组对象, 我自己写了一个js版的拷贝函数,如下:

  1. function cloneObject( o, d )
  2. {
  3. if ( o === null || o === undefined || typeof ( o ) !== 'object' )
  4. {
  5. return o;
  6. }
  7.  
  8. var deep = !!d;
  9.  
  10. var cloned;
  11.  
  12. if ( o.constructor === Array )
  13. {
  14. if ( deep === false )
  15. {
  16. return o;
  17. }
  18.  
  19. cloned = [];
  20.  
  21. for ( var i in o )
  22. {
  23. cloned.push( cloneObject( o[i], deep ) );
  24. }
  25.  
  26. return cloned;
  27. }
  28.  
  29. cloned = {};
  30.  
  31. for ( var i in o )
  32. {
  33. cloned[i] = deep ? cloneObject( o[i], true ) : o[i];
  34. }
  35.  
  36. return cloned;
  37. }

其中o是要被拷贝的对象, d指定是否要深拷贝 , 逻辑说明如下:

1 . 判断对象是否为null ,undefined, 或非object对象,如果是, 直接返回对象

2.  判断对象是否为数组,如果是,并且指定了要深拷贝,则遍历数组对象,对其成员进行深拷贝, 如果没指定为深拷贝,则直接返回数组

3.  如果是非数组对象, 遍历成员并递归处理成员对象,最后返回拷贝

 
 

javascript对象深拷贝,浅拷贝 ,支持数组的更多相关文章

  1. JavaScript之深拷贝&浅拷贝

    深拷贝&浅拷贝,说起来都明白,但是说不出所以然.今天就系统的整理下思绪,一点点的将其分析出所以然 废话不多说 浅拷贝 简单的说就是一个值引用,学生时代接触过编程的人都应该了解过指针,浅拷贝可以 ...

  2. 也来玩玩 javascript对象深拷贝,浅拷贝

    经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One method of copying an object is ...

  3. Java对象深拷贝浅拷贝总结

    目录 深拷贝 1. 手动new 2. clone方法 3. java自带序列化 4. json序列化 性能测试 深拷贝总结 浅拷贝 1. spring BeanUtils(Apache BeanUti ...

  4. Map拷贝 关于对象深拷贝 浅拷贝的问题

    问题:map拷贝时发现数据会变化. 高能预警,你看到的下面的栗子是不正确的,后面有正确的一种办法,如果需要看的话的,请看到底,感谢各同学的提醒,已做更正,一定要看到最后      先看例子:     ...

  5. JS数组和对象的浅拷贝和深拷贝

    共勉~ 在许多编程语言中,传递参数和赋值是通过值的直接复制或者引用复制完成的.在JavaScript中,对于值是直接进行复制还是引用复制在语法上是没有区别的,完全是根据值的类型来决定的. 在JavaS ...

  6. 第六章:Javascript对象

    对象是javascript的基本数据类型.对象是一种复合值.它将很多值(原始值 或者其他对象)聚合在一起.可通过名字访问这些值.对象也可以看做是属性的无序集合,每个属性都有一个名/值.属性名是字符串, ...

  7. JavaScript对象进阶

    要了解JavaScript对象,我们可以从对象创建.属性操作.对象方法这几个方面入手.概括起来,包括以下几模块: 1.创建对象 1.1 对象直接量 对象直接量是创建对象最简单的方式,由若干名/值对组成 ...

  8. javascript对象和数组之 深拷贝和浅拷贝

    管是在面试中还是我们的项目中经常会用到数组或者对象的深拷贝,下面我就自己总结的分享给大家. 首先要知道什么是深拷贝?什么是浅拷贝? 深拷贝:源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外 ...

  9. JavaScript之深拷贝和浅拷贝

    前言 工作中会经常遇到操作数组.对象的情况,你肯定会将原数组.对象进行‘备份’当真正对其操作时发现备份的也发生改变,此时你一脸懵逼,到时是为啥,不是已经备份了么,怎么备份的数组.对象也会发生变化.如果 ...

随机推荐

  1. 备份IIS httpd.ini 重写规则,兼容大部分版本号IISserver

    IISserver已经非常少,差点儿要退出市场了.nginx成为市场的主流. 备份一个httpd.ini,全部内容例如以下: [ISAPI_Rewrite] # 3600 = 1 hour Cache ...

  2. s性能优化方面的小知识

    总结的js性能优化方面的小知识 前言 一直在学习javascript,也有看过<犀利开发Jquery内核详解与实践>,对这本书的评价只有两个字犀利,可能是对javascript理解的还不够 ...

  3. Linux httpd 跳转简单方法二

    使用mod_proxy 这种方法要添加上mod_proxy_http.so 在httpd.conf 中打开httpd-vhost 在 httpd-vhost 里面添加上 <VirtualHost ...

  4. MVC页面声命周期

    MVC页面声命周期 ASP.Net请求处理机制初步探索之旅 - Part 4 WebForm页面生命周期   开篇:上一篇我们了解了所谓的请求处理管道,在众多的事件中微软开放了19个重要的事件给我们, ...

  5. 【 D3.js 入门系列 --- 9.6 】 生产的包图

    我的个人博客是:www.ourd3js.com csdn博客为:blog.csdn.net/lzhlzz 转载请注明出处,谢谢. 打包图( Pack ).用于包括与被包括的关系,也表示各个对象的权重, ...

  6. ASP.Net TextBox控件只允许输入数字

    原文:ASP.Net TextBox控件只允许输入数字 1.1.在Asp.Net TextBox 控件的 OnKeyPress 事件中指定输入键盘码必须为数字: <asp:TextBox ID= ...

  7. PHP 12 :字符串的操作

    原文:PHP 12 :字符串的操作 本章介绍字符串的操作.之所以要把字符串单独拿出来讲,是因为字符串在每种语言里都是非常重要的.并且也是大家关心的.我们从以下几个方面介绍字符串: 字符串的表现形式. ...

  8. 【COCOS2DX-游戏开发之三四】cocos2dx 3.0 TableView特殊使用方法:滚动时不能选择等等

    cocos2dx 3.0版本号TableView拍生自ScrollView,经常使用来做滚动列表,有几种特殊使用方法,不知道大家用到过没 要求:1.滚动时不能选中TableCell,非滚动状态才干选中 ...

  9. C#异步Socket示例

    C#异步Socket示例 概要 在C#领域或者说.net通信领域中有着众多的解决方案,WCF,HttpRequest,WebAPI,Remoting,socket等技术.这些技术都有着自己擅长的领域, ...

  10. leetcode第33题--Search for a Range

    Given a sorted array of integers, find the starting and ending position of a given target value. You ...