在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(); //返回数组的拷贝数组,注意是一个新的数组,不是指向

JS对象复制的更多相关文章

  1. JS对象复制(深拷贝、浅拷贝)

    如何在 JS 中复制对象 在本文中,我们将从浅拷贝(shallow copy)和深拷贝(deep copy)两个方面,介绍多种 JS 中复制对象的方法. 在开始之前,有一些基础知识值得一提:Javas ...

  2. js对象/数组深度复制

    今天碰到个问题,js对象.数组深度复制:之前有见过类似的,不过没有实现函数复制,今晚想了一下,实现代码如下: function clone(obj) { var a; if(obj instanceo ...

  3. js 对象深复制,创建对象和继承

    js 对象深复制,创建对象和继承.主要参考高级编程第三版,总结网上部分资料和自己的代码测试心得.每走一小步,就做一个小结. 1.对象/数组深复制 一般的=号传递的都是对象/数组的引用,如在控制台输入 ...

  4. js对象进行浅复制,深拷贝的方法

    js对象浅拷贝和深拷贝详解   本文为大家分享了JavaScript对象的浅拷贝和深拷贝代码,供大家参考,具体内容如下 1.浅拷贝 拷贝就是把父对像的属性,全部拷贝给子对象. 下面这个函数,就是在做拷 ...

  5. js原生设计模式——7原型模式之真正的原型模式——对象复制封装

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  6. JS对象继承篇

    JS对象继承篇 ECMAScript只支持实现继承,而且其实现继承主要是依靠原型链来实现的 原型链 其基本思路是利用原型让一个引用类型继承另一个引用类型的属性和方法 function Person() ...

  7. 【转】js实现复制到剪贴板功能,兼容所有浏览器

    两天前听了一个H5的分享,会议上有一句话,非常有感触:不是你不能,而是你对自己的要求太低.很简单的一句话,相信很多事情不是大家做不到,真的是对自己的要求太低,如果对自己要求多一点,那么你取得的进步可能 ...

  8. 纯js实现复制到剪贴板功能

    在网页上复制文本到剪切板,一般是使用JS+Flash结合的方法,网上有很多相关文章介绍.随着 HTML5 技术的发展,Flash 已经在很多场合不适用了,甚至被屏蔽.本文介绍的一款JS插件,实现了纯J ...

  9. 【原】js实现复制到剪贴板功能,兼容所有浏览器

    两天前听了一个H5的分享,会议上有一句话,非常有感触:不是你不能,而是你对自己的要求太低.很简单的一句话,相信很多事情不是大家做不到,真的是对自己的要求太低,如果对自己要求多一点,那么你取得的进步可能 ...

随机推荐

  1. C中的qsort函数和C++中的sort函数的理解与使用

    一.qsort()函数 原型:_CRTIMP void __cdecl qsort (void*, size_t, size_t,int (*)(const void*, const void*)); ...

  2. EL表达式显示数据取整问题

    第一 插入fmt标签库 <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%&g ...

  3. nginx缓存设置proxy_cache

    http://www.cnblogs.com/dudu/p/4597351.html http块: proxy_cache_path /tmp/cache levels=1:2 keys_zone=n ...

  4. excel 作图中次横坐标及次纵坐标的调试,以及excel自定义轴标签的步骤方法

    在工作中除了要做一些常用的图表之外,不时还会有一切奇怪图表的制作需求. 今天的内容主要记录的是如何对excle图表的次横坐标及次纵坐标进行调试,以及如何自定义调整轴标签 首先看下如何做次纵坐标,工作中 ...

  5. cmd中用PING命令时,出现'Ping' 不是内部或外部命令 解决方案

    在cmd中用PING命令时,出现'Ping' 不是内部或外部命令,也不是可运行的程序或批处理文件.先了解一下内容:1.可执行文件.命令文件和批处理文件以.exe或者.com或者.bat为扩展名的文件分 ...

  6. Java7的垃圾回收

    HotSpot JVM一共有4个垃圾回收器:Serial(串行).Parallel / Throughput(并行).CMS(并发).and the new kid on the block G1(G ...

  7. CSS的两大重点

    一.属性:通过属性的复杂叠加才能做出漂亮的网页 二.选择器:通过选择器找到对应的标签设置样式,选择器的作用是:选择对应的标签,为之添加样式 1>标签选择器:根据标签签名找到标签 div{     ...

  8. navicat 连接oracle 出现ora06413 连接未打开

    问题原因:未选择OCI执行DLL,和windows 64位的(x86)无关 解决方法:navicat中 工具->选项->OCI中的OCI library选择路径(navimat安装路径)C ...

  9. 史航416第八次作业&总结

    一.知识点总结: 1.数组的输入,输出及对整个数组所有元素进行操作通常都用循环结构实现. 2.可以只给部分元素赋初值.当{ }中值的个数少于元素个数时,只给前面部分元素赋值. 3.只能给元素逐个赋值, ...

  10. vim编辑二进制文件

    首先,vim -b 方式打开二进制文件, 然后用 :%!xxd去展示二进制文件 再修改文件, 最后用 :%!xxd -r去还原文件原来的展示方式, 并保存退出.