1. 程式人生 > >深度克隆:

深度克隆:

//深度克隆
function deepClone(obj){
var result,oClass=isClass(obj);
//確定result的型別
if(oClass===“Object”){
result={};
}else if(oClass===“Array”){
result=[];
}else{
return 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);
}
var oPerson={
oName:“rookiebob”,
oAge:“18”,
oAddress:{
province:“beijing”
},
ofavorite:[
“swimming”,
{reading:“history book”}
],
skill:function(){
console.log(“bob is coding”);
}
};
//深度克隆一個物件
//第一種方法、通過遞迴解析解決
var china = {
nation : ‘中國’,
birthplaces:[‘北京’,‘上海’,‘廣州’],
skincolr :‘yellow’,
friends:[‘sk’,‘ls’]
}
//深複製,要想達到深複製就需要用遞迴
function deepCopy(o,c){
var c = c || {}
for(var i in o){
if(typeof o[i] === ‘object’){
//要考慮深複製問題了
if(o[i].constructor === Array){
//這是陣列
c[i] =[]
}else{
//這是物件
c[i] = {}
}
deepCopy(o[i],c[i])
}else{
c[i] = o[i]
}
}
return c
}
var result = {name:‘result’}
result = deepCopy(china,result)
console.dir(result)

// 第二種方法:通過JSON解析解決
var test ={
name:{
xing:{
first:‘張’,
second:‘李’
},
ming:‘老頭’
},
age :40,
friend :[‘隔壁老王’,‘宋經紀’,‘同事’]
}
var result = JSON.parse(JSON.stringify(test))
result.age = 30
result.name.xing.first = ‘往’
result.friend.push(‘fdagldf;ghad’)
console.dir(test)
console.dir(result)

var oNew=deepClone(oPerson);

oNew.ofavorite[1].reading=“picture”;
console.log(oNew.ofavorite[1].reading);//picture(克隆後)
console.log(oPerson.ofavorite[1].reading);//history book(克隆前)

oNew.oAddress.province=“shanghai”;
console.log(oPerson.oAddress.province);//beijing(克隆前)
console.log(oNew.oAddress.province);//shanghai(克隆後)
從上面的程式碼可以看到,深度克隆的物件可以完全脫離原物件,我們對新物件的任何修改都不會反映到原物件中,這樣深度克隆就實現了。

這裡要注意一點的就是:為什麼deepClone這個函式中的result一定要判斷型別?這裡有一種情況,如果你的result直接是{}物件,我明明傳進去的是一個數組,結果你複製完了以後,變成了一個物件了。
//深度克隆
function deepClone(obj){
var result={},oClass=isClass(obj);
// if(oClass===“Object”){
// result={};
// }else if(oClass===“Array”){
// result=[];
// }else{
// return 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);
}
//克隆一個數組
var arr=[“a”,“b”,“c”];
var oNew=deepClone(arr);
console.log(oNew);//Object {0: “a”, 1: “b”, 2: “c”}