JS的对象复制——
Js的Number类型和String类型都不是地址引用,而是重新创建对象复制值;
var a = 1;
var b = a;
b = 2;
alert(a);
结果:1
var c = "abc";
var d = c;
d = "def";
alert(c);
结果:abc
只有对象类型才是地址引用的;
var a = {x:1};
var b = a;
b.x = 2;
alert(a.x);
结果:2
所以复制对象不要用“=”,而是遍历对象复制对象里的值,最好写个克隆方法
Jquery里有extend方法来复制对象
var objB = JQuery.extend(true, objA);
或
var objB = $.extend(true, objA);
var a = {xa:{y:1,z:"abc"},xb:{y:2,z:"def"}};
var b = jQuery.extend(true,a);
b.xb.y = 5;
alert(a.xb.y);
结果:1
但是,这时候a的类型是Object,b的类型是function?
typeof b
结果:"function"
typeof a
结果:"object"
alert(b)
结果:function (a,b){return new p.fn.init(a,b,c)}
也就是说,jQuery.extend返回的是方法本身的内存地址,b变量是指向方法的内存地址,虽然里面的值虽然是方法的return结果,但b变量并不代表一个Object
那么怎么让b连类型也复制过来呢?
b = $.clone(a);
TypeError: a.cloneNode is not a function
JQuery的克隆方法明显是克隆Dom节点的,并不能用于克隆对象
其实,只是extend方法没用好....T_T
var b = jQuery.extend(true,{},a);
在调用方法时传一个空对象为参数,extend就会将a对象的值复制给空对象,返回的就是对象,否则返回的就是方法,变量b实际指向内存地址就是传入空对象的内存地址,当然这时候已经不是空对象了。
如果没用JQuery,那自己写一个(从网上抄一个)也可以。
原理是利用递归将对象A里面的基础值一个一个复制,放到对象B里面对应参数名下就好了
下面是我自己写的test.js:
/* author:lukelsq Link:http://11163331.blog.51cto.com/ 测试 var oldObj = {xa:{y:1,z:"abc"},xb:{y:2,z:"def"}}; var newObj = new Object(); myClone(newObj,oldObj); */ function myClone(n,o){ var a; for(a in o){ if(typeof(o[a]) == "object"){ var t = new Object(); n[a] = myClone(t,o[a]); } else { n[a] = o[a]; } } return n; }
测试环境FireFox 44.0.2,测试页面只引用了jquery-1.8.0.min.js和test.js
在网上查了很多资料,非常感谢分享者。
如有错误请指正,非常感谢!