浅度克隆
浅度克隆实际上就是深度克隆第一维变量, 其他维度的变量不进行特殊处理, 当克隆出来的对象中有引用类型的属性, 那么原对象和克隆对象将使用同一个引用值
const obj = {
a: 100,
b: [10, 20, 30],
c: {
x: 10
},
d: /^\d+$/,
e: function () {
console.log(this)
}
}
function clone(obj) {
if (obj instanceof RegExp) return new RegExp(obj)
if (obj instanceof Date) return new Date(obj)
if (typeof obj === 'function') return new Function('return ' + obj)()
if (obj === null || typeof obj !== 'object') return obj
const newObj = new obj.constructor()
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key]
}
}
return newObj
}
const newObj = clone(obj)
newObj.c.x = 1000
console.log(obj.c.x) // 1000
深度克隆
深度克隆即克隆出一个值完全与原对象一致的全新对象, 每一个维度都进行深度克隆, 不论改变原对象还是克隆对象, 都不会对对方造成任何影响
深度拷贝的过程中利用递归回溯的特点构造一个全新的对象
const obj = {
a: 100,
b: [10, 20, 30],
c: {
x: 10
},
d: /^\d+$/,
e: function () {
console.log(this)
}
}
function deepClone(obj) {
if (obj instanceof RegExp) return new RegExp(obj)
if (obj instanceof Date) return new Date(obj)
if (typeof obj === 'function') return new Function('return ' + obj)()
if (obj === null || typeof obj !== 'object') return obj
const newObj = new obj.constructor()
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = deepClone(obj[key])
}
}
return newObj
}
const newObj = deepClone(obj)
newObj.c.x = 1000
console.log(obj.c.x) // 10
封装
const obj = {
a: 100,
b: [10, 20, 30],
c: {
x: 10
},
d: /^\d+$/,
e: function () {
console.log(this)
}
}
function clone(obj) {
const isDeepClone = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false
if (obj instanceof RegExp) return new RegExp(obj)
if (obj instanceof Date) return new Date(obj)
if (typeof obj === 'function') return new Function('return ' + obj)()
if (obj === null || typeof obj !== 'object') return obj
const newObj = new obj.constructor()
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = isDeepClone ? clone(obj[key], isDeepClone) : obj[key]
}
}
return newObj
}
const newObj1 = clone(obj) // 浅度克隆
const newObj2 = clone(obj, true) // 深度克隆