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