JavaScript深拷貝實現原理簡析


JavaScript實現繼承的時候,需要進行對象的拷貝;而為了不影響拷貝后的數據對原數據造成影響,也就是存在共享關系的時候,我們就需要進行深拷貝;

這里就做一個簡單的分析其實現原理

先上代碼:

var obj1 = {
    name : 'Awen',
    song : {
        auther : '小明',
        title : '廣州'
    },
    hobby: ['吃','吃吃','吃吃吃']
};
var obj2 = {};
for (var k in obj1) {
    obj2[k] = obj1[k];
}

console.log(obj2); //Object {name: "Awen", song: Object, hobby: Array[3]}
obj2['hobby'].push('喝');
console.log(obj1); //Object {name: "Awen", song: Object, hobby: Array[4]}
console.log(obj2); //Object {name: "Awen", song: Object, hobby: Array[4]}

從圖中得到結論:淺拷貝不能完成需求,對於屬性是對象的時候,只是進行簡單的地址拷貝,其引用關系也在;不符合我們的要求;

在來看下深拷貝:

function inCopy(obj1,obj2) {
    var obj1 = obj1 || {};//容錯處理
    for (var k in obj2) { 
        if(obj2.hasOwnProperty(k)){ //只拷貝實例屬性,不進行原型的拷貝
            if(typeof obj2[k] == 'object') { //引用類型的數據單獨處理
                obj1[k] = Array.isArray(obj2[k])?[]:{};
                inCopy(obj1[k],obj2[k]); //遞歸處理引用類型數據
            }else{
                obj1[k] = obj2[k]; //值類型的數據直接進行拷貝
            }
        }
    }
}

//深拷貝 兩者之間改變互不影響

//1 拷貝后兩者之間不再存在共享關系

//2 拷貝之后數據類型不能發生改變,也就是需要判斷是數組的時候,需要進行單獨遞歸的遍歷

//3 在繼承的時候,我們通過原型屬性實現原型對象屬性的繼承,在進行深拷貝的時候,我們首先需要提出原型對象上的屬性;通過hasOwnProperty方法來進行篩選;

測試代碼及結果如下

var obj3 = {
    name : 'Awen',
    song : {
        auther : '小明',
        title : '廣州'
    },
    hobby : ['吃','吃吃','吃吃吃']
};
var obj4 = {};

inCopy(obj4,obj3);
console.log(obj3); //Object {name: "Awen", song: Object, hobby: Array[3]}
console.log(obj4); //Object {name: "Awen", song: Object, hobby: Array[3]}
obj4.hobby.pop(); 
console.log(obj3); //Object {name: "Awen", song: Object, hobby: Array[3]}
console.log(obj4); //Object {name: "Awen", song: Object, hobby: Array[2]}
obj4.song.title = '北京';
console.log(obj3);
console.log(obj4);

1 刪除新對象的數據最后一項;(互不影響)

JavaScript深拷貝實現原理簡析附代碼

obj4動態pop最后一項

2 動態修改對象屬性,不影響原對象,引用關系切斷

JavaScript深拷貝實現原理簡析附代碼

obj4動態改變

3 拷貝后數據類型保持一致

JavaScript深拷貝實現原理簡析附代碼

數據類型未發生改變

 


免責聲明!

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



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