在javascript中,所有的object变量之间的赋值都是传地址的,可能有同学会问哪些是object对象。举例子来说明可能会比较好:

typeof(true)    //"boolean"
typeof(1) //"number"
typeof("1") //"string"
typeof({}) //"object"
typeof([]) //"object"
typeof(null) //"object"
typeof(function(){}) //"function"

所以其实我们深复制主要需要处理的对象就是object对象,非object对象只要直接正常的赋值就好。我实现js深复制的思路就是:

  • 遍历所有该对象的属性,
  • 如果该属性是"object"则需要特殊处理,
    • 如果这个object对象比较特殊,是一个数组,那就创建一个新的数组并深复制数组里的元素
    • 如果这个object对象是个非数组对象,那直接再对它递归调用深复制方法即可。
  • 如果不是"object",则直接正常复制就行。

下面就是我的实现了:

Object.prototype.DeepCopy = function () {
var obj, i;
obj = {}; for (attr in this) {
if (this.hasOwnProperty(attr)) {
if (typeof(this[attr]) === "object") {
if (this[attr] === null) {
obj[attr] = null;
}
else if (Object.prototype.toString.call(this[attr]) === '[object Array]') {
obj[attr] = [];
for (i=0; i<this[attr].length; i++) {
obj[attr].push(this[attr][i].DeepCopy());
}
} else {
obj[attr] = this[attr].DeepCopy();
}
} else {
obj[attr] = this[attr];
}
}
}
return obj;
};

如果浏览器支持ECMAScript 5的话,为了深复制对象属性的所有特性,可以使用

Object.defineProperty(obj, attr, Object.getOwnPropertyDescriptor(this, attr));

来替代

obj[attr] = this[attr];

直接在Object.prototype上实现该方法的好处是,所有对象都会继承该方法。坏处是某些库也会改写Object对象,所以有时会发生冲突。这是需要注意的。具体使用方法如下:

Object.prototype.DeepCopy = function () { ... }
var a = { x:1 };
var b = a;
var c = a.DeepCopy();
a.x = 2;
b.x = 3;
console.log(a.x); //3
console.log(b.x); //3
console.log(c.x); //1

转载请注明出处:jerryzou.com

Javascript中的一种深复制实现的更多相关文章

  1. 对 JavaScript 中的5种主要的数据类型进行值复制

    定义一个函数 clone(),可以对 JavaScript 中的5种主要的数据类型(包括 Number.String.Object.Array.Boolean)进行值复制 使用 typeof 判断值得 ...

  2. 实现一个函数clone,使JavaScript中的5种主要的数据类型(包括Number、String、Object、Array、Boolean)进行值复制

    实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number.String.Object.Array.Boolean)进行值复制. 1 /** 对象克隆 2 * 支持基本 ...

  3. 探究JavaScript中的五种事件处理程序

    探究JavaScript中的五种事件处理程序 我们知道JavaScript与HTML之间的交互是通过事件实现的.事件最早是在IE3和Netscape Navigator 2中出现的,当时是作为分担服务 ...

  4. JavaScript中的三种弹出对话框

    学习过js的小伙伴会发现,我们在一些实例中用到了alert()方法.prompt()方法.prompt()方法,他们都是在屏幕上弹出一个对话框,并且在上面显示括号内的内容,使用这种方法使得页面的交互性 ...

  5. JavaScript中的三种弹出框的区别与使用

    JavaScript中有三种原生的弹出框,分别是alert.confirm.prompt.分别表示弹出框.确认框.信息框. 以下是示例代码: <!DOCTYPE html> <htm ...

  6. JavaScript 中的12种循环遍历方法

    原文:JavaScript 中的12种循环遍历方法 题目:请介绍 JavaScript 中有哪些循环和遍历的方法,说说它们的应用场景和优缺点? 1.for 循环 let arr = [1,2,3];f ...

  7. 好文:javascript中的四种循环

    https://juejin.im/entry/5a1654e951882554b8373622?utm_medium=hao.caibaojian.com&utm_source=hao.ca ...

  8. JavaScript中的两种全局对象

    这里总结的东西特别适合先学习c/c++, Java这类标准语言再学JS的童鞋们看,因为JS在程序执行之前就会初始化一个全局对象,这个全局对象到底是什么是跟JS程序运行环境有关的. 根据JavaScri ...

  9. Javascript中的五种数据类型

    Undefined 未定义.只有一个值undefined Null         只有一个值,null Boolean 在javascript中,只要逻辑表达式不返回undefined不返回null ...

随机推荐

  1. Category的使用

    1.创建一个objective-c file , 可以选择 category, extension ,protocol, empty 文件.选category 就能建立类别. category机制,它 ...

  2. Python标准库12 数学与随机数 (math包,random包)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们已经在Python运算中看到Python最基本的数学运算功能.此外,math包 ...

  3. gridView自动列宽代码

    gridView1.OptionsView.ColumnAutoWidth = false; for (int I = 0; I < gridView1.Columns.Count; I++) ...

  4. linux命令行与shell脚本编程大全---bash shell命令

    PS1 =“[\t][\u]\$”                  //新的shell提示符显示了当前时间和用户名 在Windows中,你经常看到这样的文件路径:D:\work\FTL moniqi ...

  5. [SQL]开启事物,当两条插入语句有出现错误的时候,没有错误的就插入到表中,错误的语句不影响到正确的插入语句

    begin transaction mustt insert into student values(,'kkk','j大洒扫','j','djhdjh') insert into student v ...

  6. [HDU 2126] Buy the souvenirs (动态规划)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2126 题意:给你n个物品,m元钱,问你最多能买个多少物品,并且有多少种解决方案. 一开始想到的是,先解 ...

  7. VS2010 Win32项目的源码位置设置

    在VS2010中,我们可以创建一个Win32项目用来编辑C或CPP代码,项目建好后我们向项目文件夹添加代码文件,并调试能正常运行. 有时候我们会发现项目目录下没有源文件,这种情况下,可以通过设置“输出 ...

  8. c# .NET 进行数据库备份和还原

    本文主要内容来源stswordman的介绍,开发环境为10,数据库为08R2 原文地址http://www.cnblogs.com/stswordman/archive/2006/08/06/4690 ...

  9. ubuntu中VNC的安装配置笔记

    使用服务器时,利用远程桌面是非常方便的,否则需要跑到服务器机房操作非常的费事,或者需要远程操作机器是也可以使用,一般的操作系统都会带有远程桌面功能,但是不如第三方的的软件好用,对于linux系统常用的 ...

  10. Linux下串口ttyS2,ttyS3不能用的问题解决办法

    PC104,Xlinux下,突然发现串口3,4不能用... 以为是硬件的问题,换成wince后,3,4工作正常,排除电路问题 在linux下查看dmesg: serial8250: ttyS0 at ...