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

在网上查了很多资料,非常感谢分享者。

如有错误请指正,非常感谢!