经常看到讨论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. (转)Linux服务器调优

    Linux内核参数 http://space.itpub.net/17283404/viewspace-694350 net.ipv4.tcp_syncookies = 1 表示开启SYN Cooki ...

  2. c语言到汇编的学习

    [内存结构] C程序通过编译-汇编-连接,最后到可执行文件.载入内存有这几个部分: text:正文段,存放的是可执行的机器码段 data:存放初始化之后的全局变量和静态变量 bbs:存放未初始化的静态 ...

  3. 酷狗 KRC 文件的解析

    清理硬盘发现以前写过一个进行一半的代码,这次补全并从硬盘删掉. 格式说明来自 https://shansing.com/read/392/ krc解码并解压缩后得到一个字符串,例子: [id:$000 ...

  4. 让 File Transfer Manager 在新版本WIndows上能用

    最近研究.NET NATIVE,听说发布了第二个预览版,增加了X86支持,所以下,发现连接到的页面是:https://connect.microsoft.com/VisualStudio/Downlo ...

  5. leveldb源码学习系列

    楼主从2014年7月份开始学习<>,由于书籍比较抽象,为了加深思考,同时开始了Google leveldb的源码学习,主要是想学习leveldb的设计思想和Google的C++编程规范.目 ...

  6. GOOGLE PROTOBUF开发者指南

    原文地址:http://www.cppblog.com/liquidx/archive/2009/06/23/88366.html 译者: gashero 目录 1   概览 1.1   什么是pro ...

  7. Redis系列-冷知识

    下面是一些看了,但觉得用处不大,不记下又可惜的东西. Redis删除过期数据 redis通过expire/expireat(秒为单位)或者pexpire/pexpireat(毫秒为单位)来设置key的 ...

  8. java内部类技术提炼

    创作时间:2016.07.28,2016.07.29 本人qq:992591601,欢迎交流. 参考书籍:<Thinking in Java>.<Effective Java> ...

  9. ssl小结

    有几篇不错的文章: http://www.cnblogs.com/pen-ink/archive/2011/01/17/1937680.html 这个应该是最简单的示例了. 不过,当两个passwor ...

  10. 题目一:打印出所有的 "水仙花数 ",所谓 "水仙花数 "是指一个三位数,其各位数字立方和等于该数本身。例如:153是一个 "水仙花数 ",因为153=1的三次方+5的三次方+3的三次方。