js中對象的拷貝


淺拷貝(shellow copy)

先看下邊一個例子:

Object.prototype.clone = function () {
  var newObj = {},
        self = this;
  for (var i in self) {
    newObj[i] = self[i];
  }
  return newObj;
}

var obj = {
  name:"老李頭",
  hobby:["敲代碼","壓馬路"]
}

var _obj = obj.clone();
obj.hobby.push("打籃球");
console.log(obj.hobby);//["敲代碼", "壓馬路", "打籃球"]
console.log(_obj.hobby);//["敲代碼", "壓馬路", "打籃球"]

  就像我們看到的,淺拷貝只能復制基本類型的屬性,而對於共享對象類型的屬性則沒有辦法。

深拷貝 (deep copy)

在使用深拷貝復制對象時,由於數據類型的不確定性,可能為對象,數組,函數,也可能是以上幾種的嵌套。這個時候我們就需要借助遞歸

Object.prototype.clone = function () {
  var self = this,
        newObj = {};
  for(var i in self ){
    if( typeof (self[i]) == "object" || typeof (self[i]) == "function"){
      newObj[i] = self[i].clone();
    }else{
      newObj[i] = self[i];
    }
  }
  return newObj;
}

Array.prototype.clone = function () {
  var self = this,
        newArr = [];
  for(var i=0,len=self.length;i<len;i++){
   if( typeof (self[i]) == "object" || typeof (self[i]) == "function"){
      newArr [i] = self[i].clone();
    }else{
      newArr [i] = self[i];
    }
  }
  return newArr;
}    

Function.prototype.clone = function () {
  var self = this,
        newFn = function () {
          return self.apply(this,arguments);
        };
   for(var i in self){
     newFn[i] = self[i];
   }
  return newFn;
}

var obj = { 
 name: 'byvoid', 
 likes: ['node'], 
 display: function() { 
 console.log(this.name); 
 }, 
}; 
var newObj = obj.clone(); 
newObj.likes.push('python'); 
console.log(obj.likes); // 輸出 [ 'node' ] 
console.log(newObj.likes); // 輸出 [ 'node', 'python' ] 
console.log(newObj.display == obj.display); // 輸出 false 

  上面這個實現看起來很完美,它不僅遞歸地復制了對象復雜的結構,還實現了函數的深拷貝。這個方法在大多數情況下都很好用,但有一種情況它卻無能為力,例如下面的代碼:

var obj1 = {
  ref:null
};
var obj2 = {
  ref:obj1
};
obj1.ref = obj2;

  這段代碼的邏輯非常簡單,就是兩個相互引用的對象。當我們試圖使用深拷貝來復制obj1 和 obj2 中的任何一個時,問題就出現了。因為深拷貝的做法是遇到對象就進行遞歸復制,那么結果只能無限循環下去。對於這種情況,簡單的遞歸已經無法解決。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM