深淺拷貝的解決方案
阿新 • • 發佈:2018-11-24
複製基本資料型別不會有什麼問題,但是如果是引用資料型別,就會相互之間影響。
一般在資料結構比較簡單的情況下,使用淺拷貝就可以達到需求,如果資料結構比較複雜,就必須使用深拷貝。
淺拷貝:
第一種: 使用 for...in來進行淺拷貝
var book = { name: 'JS修煉' } var obj = {} for (var v in book) { obj[v] = book[v] } book.name = '我是book'
第二種: 使用Object.assign進行淺拷貝
var book = { name: 'JS修煉' } var obj2 = Object.assign({},book)
在修改了book裡面的資料後,不會影響到新拷貝的資料,這樣就實現了淺拷貝
但是在使用淺拷貝的時候,如果物件裡面還包含別的引用型別,那麼如果修改這裡面的物件,就會影響到拷貝的資料
var book = { name: 'JS修煉', list: { a: '我是a', b: '我是b', c:'我是c' } } var obj = {} for (var v in book) { obj[v] = book[v] } var obj2 = Object.assign({},book) book.name = '我是book' book.list.a = '我是修改book'
得到的結果,會影響拷貝到的資料
深拷貝:
第一種:將資料轉為字串的形式然後再進行解析
var book = { name: 'JS修煉', list: { a:'我是a', b: '我是b', c: '我是c' } } var obj = JSON.parse(JSON.stringify(book)); book.name = '我是book' book.list.a = '我是修改book' console.log(book,'book') console.log(obj,'obj')
這種確實比較簡單的實現了深拷貝,但是存在一個問題,不能去拷貝function,或者是空的
第二種: 遞迴的方式進行深拷貝
簡單的遞迴方式
var book = { name: 'JS修煉', age: '', age2: undefined, list: { a: '我是a', b: '我是b', c: '我是c' }, function () { } } function copy (obj) { var o = {} for (var i in obj) { if (typeof obj[i] === 'object') { o[i] = copy(obj[i]) } else { o[i] = obj[i] } } return o; } var obj2 = copy(book) book.name = '我是book' book.list.a = '我是修改book' console.log(book,'book') console.log(obj2,'obj2')
這樣簡單的遞迴方式就實現了深拷貝,但是這樣寫存在一個問題,對陣列無法做到處理
完整的程式碼如下
var book = { name: 'JS修煉', age: '', age2: undefined, list: { a: '我是a', b: '我是b', c: '我是c' }, author:['作者1','作者2'], author2:[ { value: '我是author2' } ], function () { } } function clone (obj) { var vv = null; if (typeof obj == 'object' && obj !== null) { vv = obj instanceof Array ? [] : {} for (var v in obj) { vv[v] = clone(obj[v]) } } else { vv =obj } return vv; } var obj3 = clone(book) book.name = '我是book' book.list.a = '我是修改book' book.author[0] = 'w' book.author2[0].value = 'w'