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 ,下面是测试代码

  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 = 5;
p.Address = new Address
{
ZipCode = "200000",
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之深拷贝&浅拷贝

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

  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. pyqt学习总结

    一.学习来由: 近期一段时间,应朋友的须要,完毕一款抓取软件.一般而言,python是我比較熟悉的语言,又有丰富的抓取和解析模块,所以果断选择之. 而这远远不是重点,后台程序在工作做常常写,所以比較熟 ...

  2. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 文件夹

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 文件夹 第一部分--開始使用SharePoint 2013 第1章节--SharePoint 2013 介绍 逐渐了解Sh ...

  3. CSS学习笔记之元素分类

    在讲解CSS布局之前,我们需要提前知道一些知识,在CSS中,html中的标签元素大体被分为三种不同的类型:块状元素.内联元素(又叫行内元素)和内联块状元素. 常用的块状元素有: <div> ...

  4. 编写高效的jQuery代码

    http://www.css88.com/jqapi-1.9/ 编写高效的jQuery代码 最近写了很多的js,虽然效果都实现了,但是总感觉自己写的js在性能上还能有很大的提升.本文我计划总结一些网上 ...

  5. 大约PF_RING/Intel 82599/透明VPN一些事

    接近崩溃的边缘,如今,在医院这篇文章地方的想法,小病,我宁愿不吃药瓶.一台笔记本电脑,但无法上网,我不称职.想知道的东西.唯一可用3G,不开的热点.由于没人给我报销流程.这个周末,我只有一天,由于下雨 ...

  6. FineUI开发实践

    ASP.NET-FineUI开发实践-7 摘要: 下拉显示grid列表.其实很简单,但是试了很多方法,水平有限,主要是都不好使,还是简单的好使了,分享下.先是看了看网上的,是直接写个了extjs控件类 ...

  7. sql 行转列总结

    原文:sql 行转列总结 PIVOT UNPIVOT的用法 PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PI ...

  8. sql语句 面试题

    ql语句 面试题   自动编号   学号   姓名 课程编号 课程名称 分数 1        2005001  张三  0001      数学    69 2        2005002  李四 ...

  9. SpringMVC类型转换、数据绑定

    SpringMVC类型转换.数据绑定详解[附带源码分析] 目录 前言 属性编辑器介绍 重要接口和类介绍 部分类和接口测试 源码分析 编写自定义的属性编辑器 总结 参考资料 前言 SpringMVC是目 ...

  10. PLAN: step one

    1. 熟悉Unix/Linux Shell和常见的命令行  (start : 7.9 - end: 7.12) 1.文件系统结构和基本操作 ls/chmod/chown/rm/find/ln/cat/ ...