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 刪除新對象的數據最后一項;(互不影響)

obj4動態pop最后一項
2 動態修改對象屬性,不影響原對象,引用關系切斷

obj4動態改變
3 拷貝后數據類型保持一致

數據類型未發生改變
