javascript深度克隆

js有两种数据类型:
  基本类型(包括undefined,Null,boolean,String,Number),按值传递;
  引用类型(包括Array,Object),按址传递,引用类型在值传递的时候是内存中的地址。
克隆或者拷贝分为2种:
  

浅度克隆:基本类型为值传递,对象仍为引用传递。

 1 var oPerson={
 2     oName:"rookiebob",
 3     oAge:"18",
 4     oAddress:{
 5         province:"beijing"
 6     },    
 7     ofavorite:[
 8         "swimming",
 9         {reading:"history book"}
10     ],
11     skill:function(){
12         console.log("bob is coding");
13     }
14 };
15 function clone(obj){
16     var result={};
17     for(key in obj){
18         result[key]=obj[key];
19     }
20     return result;
21 }
22 var oNew=clone(oPerson);
23 console.log(oPerson.oAddress.province);//beijing
24 oNew.oAddress.province="shanghai";
25 console.log(oPerson.oAddress.province);//shanghai

 

深度克隆:所有元素或属性均完全克隆,并于原引用类型完全独立。即,在后面修改对象的属性的时候,原对象不会被修改。 

function deepClone(obj){
    var result,oClass=isClass(obj);
        //确定result的类型
    if(oClass==="Object"){
        result={};
    }else if(oClass==="Array"){
        result=[];
    }else{
        return obj;//用return result=obj会大幅增加时间复杂度
    }
    for(key in obj){
        var copy=obj[key];
        if(isClass(copy)=="Object"){
            result[key]=arguments.callee(copy);//递归调用本身
        }else if(isClass(copy)=="Array"){
            result[key]=arguments.callee(copy);
        }else{
            result[key]=obj[key];
        }
    }
    return result;
}
//返回传递给他的任意对象的类
function isClass(o){
    if(o===null) return "Null";
    if(o===undefined) return "Undefined";
    return Object.prototype.toString.call(o).slice(8,-1);//返回[Object Type],故需从第8个元素开始截取type内容
}
var srcObj = {
    a: 1,
    b: {
        b1: ["hello", "hi"],
        b2: "JavaScript"
    }
};
var abObj = srcObj;
var tarObj = deepClone(srcObj);

srcObj.a = 2;
srcObj.b.b1[0] = "Hello";

console.log(abObj.a);//2
console.log(abObj.b.b1[0]);//Hello

console.log(tarObj.a);      // 1
console.log(tarObj.b.b1[0]); //hello
 

 

posted @ 2015-05-09 11:26  非额  阅读(306)  评论(0编辑  收藏  举报