经常看到讨论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 ,下面是测试代码

  public class Address
{
public string ZipCode { get; set; }
public string City { get; set; }
} public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Address Address { get; set; } /// <summary>
/// 暴露浅拷贝功能
/// </summary>
/// <returns></returns>
public Person Clone()
{
return this.MemberwiseClone() as Person;
}
}
class Program
{
static void Main(string[] args)
{
Person p = new Person();
p.Name = "leon";
p.Age = ;
p.Address = new Address
{
ZipCode = "",
City = "Shanghai"
}; Person copy = p.Clone(); copy.Address.City = "beijing"; Console.WriteLine(p.Address.City); // print beijing Console.Read();
}
}

c#中的深拷贝

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

javascript 也来玩玩拷贝

javascript 浅拷贝对象

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

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

 function shallowCopy( o )
{
var copy = {};
for ( var i in o )
{
copy[i] = o[i];
} return copy;
}

javascript 深拷贝对象

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

  function cloneObject( o, d )
{
if ( o === null || o === undefined || typeof ( o ) !== 'object' )
{
return o;
} var deep = !!d; var cloned; if ( o.constructor === Array )
{
if ( deep === false )
{
return o;
} cloned = []; for ( var i in o )
{
cloned.push( cloneObject( o[i], deep ) );
} return cloned;
} cloned = {}; for ( var i in o )
{
cloned[i] = deep ? cloneObject( o[i], true ) : o[i];
} return cloned;
}

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

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

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

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

也来玩玩 javascript对象深拷贝,浅拷贝的更多相关文章

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

    javascript对象深拷贝,浅拷贝 ,支持数组 经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One meth ...

  2. JavaScript之深拷贝&浅拷贝

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

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

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

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

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

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

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

  6. JavaScript之深拷贝和浅拷贝

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

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

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

  8. JavaScript的深拷贝和浅拷贝总结

    深拷贝和浅拷贝 深拷贝:拷贝实例:浅拷贝:拷贝引用(原对象). 说深拷贝和浅拷贝之前,我先去了解了下高程书上的JavaScript的变量类型: 基本类型:undefined.null.Boolean. ...

  9. JavaScript的深拷贝和浅拷贝

    一.数据类型 数据分为基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)和对象数据类型.. 1.基本数据类型的特点:直接存储在栈(stack ...

随机推荐

  1. Restful.Data v2.0发布,谢谢你们的支持和鼓励

    v1.0发布后,承蒙各位博友们的热心关注,也给我不少意见和建议,在此我真诚的感谢 @冰麟轻武 等朋友,你们的支持和鼓励,是这个开源项目最大的推动力. v2.0在除了细枝末节外,在功能上主要做了一下更新 ...

  2. [Asp.net 开发系列之SignalR篇]专题六:使用SignalR实现消息提醒

    一.引言 前面一篇文章我介绍了如何使用SignalR实现图片的传输,然后对于即时通讯应用来说,消息提醒是必不可少的.现在很多网站的都有新消息的提醒功能.自然对于SignalR系列也少不了这个功能的实现 ...

  3. 浅谈Excel开发:九 Excel 开发中遇到的常见问题及解决方法

    Excel开发过程中有时候会遇到各种奇怪的问题,下面就列出一些本人在开发中遇到的一些比较典型的问题,并给出了解决方法,希望对大家有所帮助. 一 插件调试不了以及错误导致崩溃的问题 在开发机器上,有时可 ...

  4. [ZigBee] 14、Zigbee无线通信前奏——BasicRF 简单无线点对点传输协议

    本工程不带zigbee协议栈,作为过渡 实验现象: 一个EB2530(终端A)定义为发射模块,另一个EB2530(终端B)定义为接收模块. 按EB2530(终端A)上的按键,无线控制另一个EB2530 ...

  5. 简述Python模块和包

    我们常常会使用别人写的包,假如我们使用的是Python3.4版本,安装在windows的C盘根目录下,那么外部的包一般放在:C:\Python34\Lib\sit-packages下,此目录下有以.p ...

  6. JavaScript 误区

    接触JavaScript两年多遇到过各种错误,其中有一些让人防不胜防,原来对JavaScript的误会如此之深,仅以此文总结一下常见的各种想当然的误区 String replace string的re ...

  7. mysql: error while loading shared libraries: libmysqlclient.so.16

    [root@host_41 mysql]# mysqlmysql: error while loading shared libraries: libmysqlclient.so.16: cannot ...

  8. Mac OS 环境下 安装 Asp.Net及使用Yeoman 创建Asp.Net 项目

    本文是按照英文原文:Installing ASP.NET 5 On Mac OS安装时遇到的问题的总结Blog. 原文提示如下: Installing ASP.NET 5 On Mac OS XBy ...

  9. 说说设计模式~门面模式(Facade)

    返回目录 门面模式(Facade)属于结构型模式的一种,它符合面向对象的封装原则,但又不符合开闭原则,呵呵,今天我们主要说它的优点,不谈缺点. 定义 门面模式,是指提供一个统一的接口去访问多个子系统的 ...

  10. EF架构~CodeFirst自关联表的插入

    回到目录 这个文章对之前EF的一个补充,对于一些自关联表的添加,如果你建立了表约束确实有这种问题,一般主键为整形自增,父ID为可空,这时,在添加时如果不为ID赋值,结果就会出错. 错误: 无法确定依赖 ...