在工作中遇到了深浅复制的问题,所以详细总结一下:

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

  1. var obj = { a:1, arr: [2,3] };
  2. var shadowObj = shadowCopy(obj);
  3.  
  4. function shadowCopy(src) {
  5. var dst = {};
  6. for (var prop in src) {
  7. if (src.hasOwnProperty(prop)) {
  8. dst[prop] = src[prop];
  9. }
  10. }
  11. return dst;
  12. }

这是一种典型的浅复制,shadowCopy方法将对象的各个属性进行依次复制,并不会进行递归复制,而 JavaScript 存储对象都是存地址的,所以浅复制会导致 obj.arr 和 shadowObj.arr 指向同一块内存地址。当其中一个变量对指向的值做了修改,另一个变量在调用时数值也就修改了。

  1. shadowObj.arr[1] = 5;
  2. obj.arr[1] // = 5

下面给出深复制的代码:

  1. function deepCopy ( obj ) {
  2. var tmp = {};
  3. for ( var k in obj ) {
  4. tmp[ k ] = obj[ k ];
  5. }
  6. return tmp;
  7. }
  8. //在这个函数中最关键的一步 tmp[ k ] = obj[ k ]
  9. //所以这里只需要保证 obj[ k ] 这个赋值是一个深度拷贝的对象即可.
  10. //注意: 函数的目的是得到 obj 的深拷贝副本. 因此递归一下.
  11.  
  12. function deepCopy ( obj ) {
  13. var tmp = {}, k;
  14. for ( k in obj ) {
  15. if ( typeof obj[ k ] === 'object' ) {
  16. tmp[ k ] = deepCopy( obj[ k ] );
  17. } else {
  18. tmp[ k ] = obj[ k ];
  19. }
  20. }
  21. return tmp;
  22. }
  23.  
  24. // 如果处理这个对象
  25. var o3 = {
  26. name: 'jim',
  27. scores: [
  28. 90,
  29. 95,
  30. 85
  31. ]
  32. };
  33.  
  34. // 该代码无法处理数组的情况,做如下改动
  35. function deepCopy ( obj ) {
  36. var tmp = obj.length >= 0 ?
  37. obj instanceof Array ? [] : { length: 0 } :
  38. {},
  39. k;
  40. for ( k in obj ) {
  41. if ( typeof obj[ k ] === 'object' ) {
  42. tmp[ k ] = deepCopy( obj[ k ] );
  43. } else {
  44. tmp[ k ] = obj[ k ];
  45. }
  46. }
  47. return tmp;
  48. }

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

JSON.parse( JSON.stringify(a) )这种方法比较简单,但同时也存在问题

  • 无法复制函数
  • 原型链没了,对象就是object,所属的类没了。这会抛弃对象的constructor,也就是深复制之后,无论这个对象原本的构造函数是什么,在深复制之后都会变成Object。另外诸如RegExp对象是无法通过这种方式深复制的。

javaScript 深层复制的更多相关文章

  1. java数组对象的浅层复制与深层复制

    实际上,java中数组对象的浅层复制只是复制了对象的引用(参考),而深层复制的才是对象所代表的值.

  2. javascript禁止复制网页内容,兼容三大浏览器

    javascript禁止复制网页内容可以通过以下方式实现:禁止鼠标右键+禁止选中文本. 代码很简单,只需要在head标签的javascript内加入以下两行代码即可. document.onconte ...

  3. js中的深层复制

    同java一样,数据的复制,不小心就是一个浅复制,莫名其妙的数据就被修改了,所以我们需要考虑深层复制的问题.这里提供一个深层复制的方法. 1.脚本 /** * 深层复制 */ cloneObject ...

  4. Java深层复制方式

    为什么需要深层复制 Object 的 clone() 方法是浅层复制(但是 native 很高效).另外,Java 提供了数组和集合的复制方法,分别是 Arrays.copy() 和 Collecti ...

  5. c++中深层复制(浅层复制运行错误)成功运行-----sample

    下面随笔给出c++中深层复制(浅层复制运行错误)成功运行------sample. 浅层复制与深层复制 浅层复制 实现对象间数据元素的一一对应复制. 深层复制 当被复制的对象数据成员是指针类型时,不是 ...

  6. 【javascript】复制到剪贴板功能(支持目前各种浏览器)

    本demo支持各种浏览器复制,亲测可用(IE8,IE9,IE10,火狐,谷歌). 本demo中使用了ZeroClipboard(下载地址:https://github.com/zeroclipboar ...

  7. Javascript 实现复制(Copy)动作方法大全

    一.实现点击按钮,复制文本框中的的内容 <script type="text/javascript"> function copyUrl2() { var Url2=d ...

  8. JavaScript对象复制(一)(转载)

    在JavaScript很多人复制一个对象的时候都是直接用"=",因为大家都觉得脚本语言是没有指针.引用.地址之类的,所以直接用"="就可以把一个对象复制给另外一 ...

  9. javascript 复制与粘贴操作

    <script language="javascript"> function readTxt() { alert(window.clipboardData.getDa ...

随机推荐

  1. 模拟浏览器的GET和POST动作

    Jakarta的httpclient3.1是最新版本,项目中需要用程序模拟浏览器的GET和POST动作.在使用过程中遇到不少问题.1. 带附件的POST提交    最开始都是使用MultipartPo ...

  2. [MySQL] lock知识梳理

    MySQL Lock机制 INDEX: MySQL事务隔离级别 MVCC MySQL Lock类型 MySQL MDL CONTENT: 1. MySQL事务隔离级别 Read Uncommit RU ...

  3. 模块(python的标准库)

    在python中叫做模块,其他语言中叫做类库.python中的模块有三种:内置模块,第三方模块,自定义模块. 模块的使用: 先导入,import+模块名,再使用,模块名+函数名() .py文件与.py ...

  4. AC日记——[Sdoi2010]星际竞速 bzoj 1927

    1927 思路: 连边,拆点: 每个点拆成i,i+n,都向t连边: i到t表示高速模式,i+n到t表示跳跃模式: 然后读入路径,如果u>v,则交换u,v: u向v+n连边: spfa跑最小费用: ...

  5. Oracle 时间字符 转

    http://www.cnblogs.com/linximf/archive/2011/11/21/2257036.html oracle数据类型看起来非常简单,但用起来会发现有许多知识点,本文是我对 ...

  6. jzyzoj 栈——P1148:括号匹配加强版

    括号匹配加强版 描述 Description 对于一个由(,),[,]括号组成的字符串,求出其中最长的括号匹配字串. 具体来说,满足如下条件的字符串成为括号匹配的字符串: (1) (),[] 是括号匹 ...

  7. jquery中的数据传输

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...

  8. php的session与免登陆问题

    Session 与 Session的GC 由于PHP的工作机制,它并没有一个daemon线程来定期的扫描Session 信息并判断其是否失效,当一个有效的请求发生时,PHP 会根据全局变量 sessi ...

  9. eclipse运行时弹出Fail to create the Java Virtual Machine

    找到eclipse程序所在目录,在目录下找到eclipse.ini文件,打开文件将com.android.ide.eclipse.adt.package.product下的值改成128m,org.ec ...

  10. 如何部署和运行Scut服务器及游戏:Windows篇

    概述 Scut游戏引擎是一个永久免费的全脚本游戏服务器框架,采用MVC框架设计,简化数据库设计和编码工作:降低对开发人员的开发难度:同时提供了丰富的类库和API接口. 一.    安装环境 必须安装的 ...