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

var i1 = 1;
var i2 = i1;
i2 = 2;
alert("i1:"+i1+",i2:"+i2);

输出结果:i1:1 , i2:2

但可能没有发现,这种“复制”用在对象(object)类型是“错误”的,因为这只是把对象的地址复制,所以如下代码会进行了一次“错误”的复制:
代码2

var o1 = {i : 1,s : "o1"};
var o2 = o1;
o2.i=2;
o2.s="o2";
alert("o1.i:"+o1.i+",o2.i:"+o2.i);
alert("o1.s:"+o1.s+",o2.s:"+o2.s);

输出:o1.i:2 , o2.i:2
      o1.s:o2 , o2.s:o2

可能你会问为什么 代码1 可以复制,但 代码2 却没有复制?
    其实准确来说是“基本数据类型”可以复制,非基本类型(包括字符串)只复制其引用。为什么要这样做呢?原因很简单,为了减少开销。大家都知道非基本类型有时候很大,如果重新开辟内存来存放一个这么大的对象,开销很大,导致运行会很慢。脚本语言是直接在虚拟机(或者浏览器)运行,它经过虚拟机这一层来处理代码,速度已经相对其他编译语言慢很多,所以如果把非基本对象再做“复制”,那么可能你要等上一年半载才能运行得了程序,因此只能复制对象的引用。

但很多时候我们并不希望函数去修改我们的这些对象参数,这就需要使用到对象的克隆,我们应该对该对象做一个克隆,然后操作这个克隆的对象,这样就不会影响我们的原对象了。 如果需要把整个对象复制,必须一个一个属性或方法引用复制一偏,这样为每个属性开辟内存来存放你需要的数据,当然这样相对来说会很慢,尤其数据量很多的时候, 在js中并没有对象克隆功能,因此需要我们自己实现,实现方法也不复杂,基本上是做一些属性复制,我在网上找了一些,但有些实现并不好,如对于array对象克隆后就成json对象了,并没有保留原来的数组方式。不过最后还是找到了一个很好的克隆函数,完美实现了js对象的克隆功能,不论是Array对象或者是普通的Object,都可以很好的进行克隆,这个函数使用constructor(函数构造器)进行复制。

方法一:

Object.prototype.Clone = function(){
var objClone;
if (this.constructor == Object){
objClone = new this.constructor();
}else{
objClone = new this.constructor(this.valueOf());
}
for(var key in this){
if ( objClone[key] != this[key] ){
if ( typeof(this[key]) == 'object' ){
objClone[key] = this[key].Clone();
}else{
objClone[key] = this[key];
}
}
}
objClone.toString = this.toString;
objClone.valueOf = this.valueOf;
return objClone;
}

方法二:

function clone(obj){
var o;
switch(typeof obj){
case 'undefined': break;
case 'string' : o = obj + '';break;
case 'number' : o = obj - 0;break;
case 'boolean' : o = obj;break;
case 'object' :
if(obj === null){
o = null;
}else{
if(obj instanceof Array){
o = [];
for(var i = 0, len = obj.length; i < len; i++){
o.push(clone(obj[i]));
}
}else{
o = {};
for(var k in obj){
o[k] = clone(obj[k]);
}
}
}
break;
default:
o = obj;break;
}
return o;
}

方法三:

function clone3(obj){
function Clone(){}
Clone.prototype = obj;
var o = new Clone();
for(var a in o){
if(typeof o[a] == "object") {
o[a] = clone3(o[a]);
}
}
return o;
}

方法四:

arrayObj=[1,2,3,4,5];

arrayObj.slice(0); //返回数组的拷贝数组,注意是一个新的数组,不是指向

arrayObj.concat(); //返回数组的拷贝数组,注意是一个新的数组,不是指向

转载地址http://www.cnblogs.com/zhangzili/p/3805935.html

最新文章

  1. 软件测试基础homework3
  2. Leetcode: Bomb Enemy
  3. Spring基本框架
  4. 剑指Offer 反转链表
  5. selenium grid中的多个线程同步执行
  6. mysql 在大型应用中的架构演变
  7. Makefile中include、-include、sinclude的区别
  8. Windows平台下,Scrapy Installation,安装问题解决
  9. UVA 12125 March of the Penguins
  10. 程序猿的量化交易之路(26)--Cointrader之Listing挂牌实体(13)
  11. 扫码JSP
  12. ASP.NET Core MVC压缩样式、脚本及总是复制文件到输出目录
  13. Hive thrift服务(将Hive作为一个服务器,其他机器可以作为客户端进行访问)
  14. 在 Vue 结合 Axios 使用过程 中 post 方法,后台无法接受到数据问题
  15. C++接口与实现的抽象分离
  16. Beyond Compare 4 提示错误“这个授权密钥已被吊销”的解决办法
  17. kubernets基础
  18. MD5在线加密的应用
  19. 向安装包中添加设备 UDID. 蒲公英内测
  20. 巧用CurrentThread.Name来统一标识日志记录

热门文章

  1. 仙人掌 &amp;&amp; 圆方树 &amp;&amp; 虚树 总结
  2. 19 Zabbix web监控实例
  3. 自学Zabbix8.1 Regular expressions 正则表达式
  4. BZOJ 1195: [HNOI2006]最短母串
  5. SDL2.0 VLC ubuntu安装和黑屏问题
  6. A1028. List Sorting
  7. [luoguU42591][小T的绝对值]
  8. react缓存问题
  9. checkbox用图片替换原始样式,并实现同样的功能
  10. 紧急通知:Onion勒索病毒正在大范围传播!已有大量学生中招!(转)