在JavaScript很多人复制一个对象的时候都是直接用"=",因为大家都觉得脚本语言是没有指针、引用、地址之类的,所以直接用"="就可以把一个对象复制给另外一个对象,如下代码:
代码1
1.var i1 = 1;
2.var i2 = i1;
3.i2 = 2;
4.alert("i1:"+i1+",i2:"+i2);
输出结果:i1:1 , i2:2
但可能没有发现,这种“复制”用在对象(object)类型是“错误”的,因为这只是把对象的地址复制,所以如下代码会进行了一次“错误”的复制:
代码2
1.var o1 = {i : 1,s : "o1"};
2.var o2 = o1;
3.o2.i=2;
4.o2.s="o2";
5.alert("o1.i:"+o1.i+",o2.i:"+o2.i);
6.alert("o1.s:"+o1.s+",o2.s:"+o2.s);
输出:o1.i:2 , o2.i:2
o1.s:o2 , o2.s:o2
可能你会问为什么 代码1 可以复制,但 代码2 却没有复制?
其实真确来说是基本数据类型可以复制,非基本类型(包括字符串)只复制其引用。为什么要这样做呢?原因很简单,为了减少开销。大家都知道非基本类型有时候很大,如果重新开辟内存来存放一个这么大的对象,开销很大,导致运行会很慢。脚本语言是直接在虚拟机(或者浏览器)运行,它经过虚拟机这一层来处理代码,速度已经相对其他编译语言慢很多,所以如果把非基本对象再做“复制”,那么可能你要等上一年半载才能运行得了程序,因此只能复制对象的引用。
如果需要把整个对象复制,必须一个一个属性或方法引用复制一偏,这样为每个属性开辟内存来存放你需要的数据,当然这样相对来说会很慢,尤其数据量很多的时候,下面是本人写的对象复制函数:
代码3
1.function cloneAll(fromObj,toObj){
2. for(var i in fromObj){
3. if(typeof fromObj[i] == "object"){
4. toObj[i]={};
5. cloneAll(fromObj[i],toObj[i]);
6. continue;
7. }
8. toObj[i] = fromObj[i];
9. }
10.}
把fromObj对象复制到toObj
代码1
1.var i1 = 1;
2.var i2 = i1;
3.i2 = 2;
4.alert("i1:"+i1+",i2:"+i2);
输出结果:i1:1 , i2:2
但可能没有发现,这种“复制”用在对象(object)类型是“错误”的,因为这只是把对象的地址复制,所以如下代码会进行了一次“错误”的复制:
代码2
1.var o1 = {i : 1,s : "o1"};
2.var o2 = o1;
3.o2.i=2;
4.o2.s="o2";
5.alert("o1.i:"+o1.i+",o2.i:"+o2.i);
6.alert("o1.s:"+o1.s+",o2.s:"+o2.s);
输出:o1.i:2 , o2.i:2
o1.s:o2 , o2.s:o2
可能你会问为什么 代码1 可以复制,但 代码2 却没有复制?
其实真确来说是基本数据类型可以复制,非基本类型(包括字符串)只复制其引用。为什么要这样做呢?原因很简单,为了减少开销。大家都知道非基本类型有时候很大,如果重新开辟内存来存放一个这么大的对象,开销很大,导致运行会很慢。脚本语言是直接在虚拟机(或者浏览器)运行,它经过虚拟机这一层来处理代码,速度已经相对其他编译语言慢很多,所以如果把非基本对象再做“复制”,那么可能你要等上一年半载才能运行得了程序,因此只能复制对象的引用。
如果需要把整个对象复制,必须一个一个属性或方法引用复制一偏,这样为每个属性开辟内存来存放你需要的数据,当然这样相对来说会很慢,尤其数据量很多的时候,下面是本人写的对象复制函数:
代码3
1.function cloneAll(fromObj,toObj){
2. for(var i in fromObj){
3. if(typeof fromObj[i] == "object"){
4. toObj[i]={};
5. cloneAll(fromObj[i],toObj[i]);
6. continue;
7. }
8. toObj[i] = fromObj[i];
9. }
10.}
把fromObj对象复制到toObj