在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

JavaScript对象复制(一)(转载)的更多相关文章

  1. JavaScript对象复制

    近期项目因为怕数据污染所以用到了js的对象复制 js里的对象都是继承自object,是引用类型,所以无法通过=号复制 所以整理了一些常用的复制方法,如下 一.通过JSON序列化和反序列化创建新的对象 ...

  2. Javascript 对象复制

    如果对象只是一个数据集,可采用json化再反json化的方式克隆一个对象,这个过程会丢失对象的方法.效率比较低. 可以采用如下递归的方式复制一个对象. function clone(target) { ...

  3. Javascript 对象复制(深浅拷贝)

    一.数据类型分类: 基本变量 引用类型 二.什么叫做指针指向 栈内存.堆内存.指针指向(如下红圈圈的斜线). 三.赋值.拷贝.引用区别? 赋值指一个变量赋予某个值,包含两种方式,一种是直接量,另一种, ...

  4. JavaScript对象复制(二)

    <script> function copy(a) { ret = {}; for (sth in a) { temp = a[sth]; if (temp instanceof Arra ...

  5. JavaScript对象的深浅复制

    前言 从层次上来看,对象的复制可以简单地分为浅复制和深复制,顾名思义,浅复制是指只复制一层对象的属性,不会复制对象中的对象的属性,对象的深复制会复制对象中层层嵌套的对象的属性. 在复制对象时,除了要复 ...

  6. 【转】JavaScript中的对象复制(Object Clone)

    JavaScript中并没有直接提供对象复制(Object Clone)的方法.因此下面的代码中改变对象b的时候,也就改变了对象a. a = {k1:1, k2:2, k3:3}; b = a; b. ...

  7. 转载 -- 如何判断Javascript对象是否存在

    http://www.ruanyifeng.com/blog/2011/05/how_to_judge_the_existence_of_a_global_object_in_javascript.h ...

  8. 如何深度复制一个javascript对象

    前言 最近有人问我,如何将一个对象复制一份,因为他遇到了一个需求,需要将后端获取的数据,保存一份,原始数据会因为交互而发生变化,最终需要对比两份数据的异同. 他是一个刚入行的小朋友,他的实现方式就是新 ...

  9. javaScript系列 [02]-javaScript对象探析

    [02]-javaScript对象探析 题记:多年前,以非常偶然的方式关注了微信公众号“面向对象”,本以为这个公众号主要以分享面向对象编程的干货为主,不料其乃实实在在的猿圈相亲平台.通过查看公开资料, ...

随机推荐

  1. MT【16】证明无理数(2)

    证明:$sin10^0$为无理数. 分析:此处用$sin$的三倍角公式,结合多项式有有理根必须满足的系数之间的关系可以证明. 评:证明$sin9^0$为无理数就不那么简单.思路:先利用$sin54^0 ...

  2. 【刷题】AtCoder Regular Contest 002

    A.うるう年 题意:判断闰年 做法:.. #include<bits/stdc++.h> #define ui unsigned int #define ll long long #def ...

  3. 洛谷P3959 宝藏(NOIP2017)(状压DP,子集DP)

    洛谷题目传送门 Dalao的题解多数是什么模拟退火.DFS剪枝.\(O(3^nn^2)\)的状压DP之类.蒟蒻尝试着把状压改进了一下使复杂度降到\(O(3^nn)\). 考虑到每条边的贡献跟它所在的层 ...

  4. Java新AIO/NIO2:AsynchronousServerSocketChannel和AsynchronousSocketChannel简单服务器-客户端

    Java新AIO/NIO2:AsynchronousServerSocketChannel和AsynchronousSocketChannel简单服务器-客户端用AsynchronousServerS ...

  5. Python的单向链表实现

    思路 链表由节点组成,先规定节点(Node),包含data和指向下个节点的next 初始化 data当然就是传入的data了,next指向None 添加 分两种情况: 链表为空,那么头节点和尾节点都指 ...

  6. linux一次性解压多个.gz或者.tar.gz文件

    对于解压多个.gz文件的,用此命令: for gz in *.gz; do gunzip $gz; done 对于解压多个.tar.gz文件的,用下面命令: for tar in *.tar.gz; ...

  7. emwin之LISTWHEEL控件之LISTWHEEL_SetPos函数的使用

    @2018-09-05 [小记] LISTWHEEL控件的LISTWHEEL_SetPos函数的使用注意事项: 该函数不能在创建窗口的WM_INIT_DIALOG分支下作为修改LISTWHEEL控件属 ...

  8. 洛谷 P2292 [HNOI2004] L语言 解题报告

    P2292 [HNOI2004] L语言 题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章\(T\)是由若干小写字母构成.一个单词 ...

  9. 【SPOJ283】Naptime

    题目大意:给定一个由 N 个点组成的环,点有点权,现从中选出 M 个点,对于顺时针方向来说,每一段被选取的第一个点的点权不计入答案贡献,求选出的最大权值是多少. 题解:首先考虑线性的情况,设 \(dp ...

  10. 路径或文件名中含有中文的jar文件双击启动不了 -> Java7的Bug?

    至从安装了java7后,才发现部分可执行的jar文件双击都启动不了了. 比如所有的jar文件放在桌面上双击启动不了. 比如所有的文件名中含有中文的jar文件双击启动不了. 比如一个 abc.jar 放 ...