如何通過自定義的deepclone,實現對對象,數組的深拷貝。 ...
在JavaScript中,對於引用類型來說,想要實現對一個對象的修改而不改變原來本身的對象,就需要對對象就行拷貝,拷貝分為深淺拷貝,如果一個對象或者一個數組中的value都是基本類型的話,那麼通過淺拷貝就可以將一個對象複製,並且修改屬性不會影響原來的對象,js中基本類型包括5種,分別是 String,Number,Boolean,Null,Undefined五種類型,也就是說如果你的引用類型中只有這5種類型的話,那麼你只需要通過淺拷貝就可以實現。
var newobj = Object.assign({},obj);
但是對於一些複雜的類型,僅僅通過Object.assign來說就顯得不是那麼夠了。ok,這裡有兩種方式可以實現,第一種,我們可以通過自己實現的一個deepclone來實現深拷貝
function deepclone(obj) { let newobj = Array.isArray(obj) ? [] : {}; //在這裡判斷傳入的類型然後初始化一個空的對象或數組 for(let key in obj){ let type = Object.prototype.toString.call(obj[key]);//判斷對象屬性的類型,如果為引用類型遞歸處理 if( type === '[object Array]' || type === '[object Object]'){ newobj[key] = deepclone(obj[key]); } else{ newobj[key] = obj[key]; } } return newobj; }
通過這種方法我們就實現了一個對象的深拷貝,下麵是測試的結果
var test = { score: [1,[3,4,5],3], name: 'petter', skill: { run: function () { console.log('I can run fast'); } } } var mytest = deepclone(test); mytest.name = 'jenny'; console.log('Myname is ' + test.name); mytest.score[1].push(4); console.log(mytest.score); console.log(test.score); mytest.skill.run = function () { console.log('I can\'t run fast'); } test.skill.run(); mytest.skill.run(); { score: [ 1, [ 3, 4, 5 ], 3 ], name: 'petter', skill: { run: [Function: run] } } Myname is petter [ 1, [ 3, 4, 5, 4 ], 3 ] [ 1, [ 3, 4, 5 ], 3 ] I can run fast I can't run fast
還有一種深拷貝的實現方法是通過json,當然這有點黑科技了
var newobj = JSON.parse(JSON.stringify(obj));
這種方法的缺點是對象的方法會丟失,因為對於JSON格式的數據來說是不應該有function的,所以在JSON.stringify中會幫我們將這些方法給濾掉,也就會造成丟失。
所以使用時應該多加小心。
ok,今天的總結就到這。