JS如何進行對象的深克隆(深拷貝)?


JS中,一般的賦值傳遞的都是對象/數組的引用,並沒有真正的深拷貝一個對象,如何進行對象的深拷貝呢?

var a = {name : 'miay'};
var b = a;
b.name = 'Jone';
console.log(a.name)   //Jone

上述代碼中,b指向a所指向的棧對象,也就是說a,b指向同一個棧對象,這種屬於對象的淺拷貝。

var a = {name : 'miay'};
var b = Object.assign({},a);
console.log(a === b)  //false
b.name = 'chris';
console.log(a.name)  //miya

上述代碼將原對象拷貝到一個空對象中,a,b指向的是不同的棧對象,所以對b.name重新賦值不會影響到a.name,但是如果a.name是一個對象的引用,而不是一個字符串,那么a.nam和b.name指向的棧空間就是同一個了,看下面的栗子:

var a = {name:{firstName:"tang",lastName:"jiao"}}
var b = Object.assign({},a)
console.log(a === b);  //false
b.name.firstName = "chen"
console.log(a.name.firstName) //chen

可以看出,Object.assign只是介於對象的深克隆和淺克隆之間的一種拷貝。具體來說也只是淺拷貝。對於對象屬性值為引用類型時,賦值時也是對於棧對象的引用罷了,那如何真正的進行對象的深拷貝呢?

使用JSON.parse()和JSON.stringify()對對象進行深拷貝 

var clone = function(obj){
    return JSON.parse(JSON.stringify(obj));
}
var a = {
    a:function(){console.log('hello world')},
    b:{c:1},
    c:[1,2,3],
    d:'tang',
    e:new Date(),
    f:null,
    g:undefined
}
var b = clone(a);
console.log(b)

 

可以看出,上述clone的方法會忽略function和undefined的字段,對date類型支持貌似也不友好。而且只能克隆原始對象自身的值,不能克隆它繼承的值,參考代碼如下:

function Person(name){
    this.name = name;
}
var tang = new Person('miya');
var newtang = clone(tang)
tang.constructor === Person //true
newtang.constructor === Person //false
console.log(newtang.constructor)  //ƒ Object() { [native code] }

結論:對於純數據的json對象的深克隆,可以使用JSON.parse()和JSON.stringify()方法,自己可以寫個兼容function,undefined,繼承,Date的深拷貝的方法: 

var clone = function(obj){
    if(obj === null) return null;
    if(obj.constructor !== 'object') return obj;
    if(obj.constructor === Date) return new Date(obj);
    if(obj.constructor === RegExp) return new RegExp(obj);
    var newObj = new obj.constructor(); //保持繼承的原型
    for(var key in obj){
        if(obj.hasOwnProperty(key)){
            var val = obj[key];
            newObj[key] = typeof val === 'object' ? arguments.callee(val):val;
        }
    }
    return newObj;
}

 經過驗證,上述的原型的繼承,還是function,undefined,日期,正則等都完美實現深拷貝!

這里運用的就是建立一個新的對象,進行原始對象自有屬性的拷貝,遇到引用類型則繼續該方法的執行,非引用類型直接賦值。

 

我唯一知道的就是自己的無知。【完】

【我所知道的只有一件事,那就是我什么也不知道。】 ——蘇格拉底

  [BGM] The Old Measure  ——Daniel Martin Moore

 


免責聲明!

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



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