JavaScript 深度克隆和浅度克隆

tuIE0P.jpg

浅度克隆

浅度克隆实际上就是深度克隆第一维变量, 其他维度的变量不进行特殊处理, 当克隆出来的对象中有引用类型的属性, 那么原对象和克隆对象将使用同一个引用值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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

深度克隆

深度克隆即克隆出一个值完全与原对象一致的全新对象, 每一个维度都进行深度克隆, 不论改变原对象还是克隆对象, 都不会对对方造成任何影响

深度拷贝的过程中利用递归回溯的特点构造一个全新的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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

封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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) // 深度克隆
-------------本文结束感谢阅读-------------