概念
深拷貝和淺拷貝都是針對的引用類型
- 淺拷貝:拷貝的是地址,最終兩個變量指向同一份數(shù)據(jù)究恤,修改其中一個變量會改變另一個
- 深拷貝:兩個變量是獨(dú)立的,互不影響
我們先看一個淺拷貝的例子
var a = {
name: '小明'
}
var b = // {name: "小明"}
b.name = '木木'
a // {name: "木木"}
只拷貝一層
假設(shè)拷貝一份多層嵌套的對象,淺拷貝就是只進(jìn)行一層拷貝柒爵,深拷貝就是無限層級拷貝
一層淺拷貝實現(xiàn)
var a = {
student: {
name: '木子'
}
}
function shallow(obj) {
var newObj = {}
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
newObj[i] = obj[i]
}
}
return newObj
}
var b = shallow(a)
b.student.name = 'kk'
a.student.name // "kk"
深拷貝
第一種方法:JSON.stringify()和JSON.parse()實現(xiàn)
缺點:
- 當(dāng)值為undefined、function赚爵、symbol 會在轉(zhuǎn)換過程中被忽略餐弱,所以,對象值有這三種的話用這種方法會導(dǎo)致屬性丟失
var a = {
student: {
name: '木子'
},
say: function() {
return '你好'
},
un: undefined
}
var b = JSON.parse(JSON.stringify(a)) // {student: {name: "木子"}}
b.student.name = 'kk'
a.student.name // "木子"
第二種方法:遞歸實現(xiàn)
拓展和邊界問題:
- 參數(shù)類型做校驗囱晴,不是對象直接返回
- 判讀是否是對象的邏輯
- 參數(shù)為數(shù)組的情況
function deepCopy(source) {
// 參數(shù)如果不是對象直接返回
if (typeof source !== 'object') return source
// 參數(shù)如果為數(shù)組
var newObj = Object.prototype.toString.call(source) === "[object Array]" ? [] : {}
for (var key in source) {
// 判斷是自身屬性膏蚓,而非原型上的
if (source.hasOwnProperty(key)) {
newObj[key] = typeof source[key] === 'object' ? deepCopy(source[key]) : source[key]
}
}
return newObj
}
// 測試
var a = {
arr: [1, 2, 3],
student: {
name: '木子',
depObj: {
age: 14
}
},
say: function() {
return '你好'
},
un: undefined
}
var b = deepCopy(a)
a.arr.push(4)
a.arr // [1, 2, 3, 4]
b.arr // [1, 2, 3