深拷贝和浅拷贝在实际应用中还是比较多的,这里作下总结。
什么是深拷贝?
通俗的讲就是对拷贝多层(直至所有层级),这样的拷贝就是深拷贝。
什么是浅拷贝
通俗的讲就是只拷贝一层,这样的拷贝就是浅拷贝。(PS:对于js中的5中基本类型的拷贝都属于浅拷贝)
举个例子
var a = {
a: 1,
b: {
c: '我是a中的b中的c'
},
c: [1,23,4,5]
}
var d = a;//这里就是浅拷贝
d.b.c = 'wcx';
d.c[2] = 'changed';
console.log(a);
console.log(d);
输出结果
{ a: 1, b: { c: 'wcx' }, c: [ 1, 23, 'changed', 5 ] }
{ a: 1, b: { c: 'wcx' }, c: [ 1, 23, 'changed', 5 ] }
WTF!!!,虽然复制了a(浅拷贝),但是修改d的属性怎么影响a了???。
解决方案
对于数组:
使用concat方法或者slice方法来实现
举个例子:
let a = [1,3,4,666];
let b = a.concat([]);//或者 let b = a.slice(0);
b[0] = 'test';
console.log(a, b);//输出结果: [1,3,4,666] ['test',3,4,666]
对于对象(同样适用数组和对象的混合类型以及纯数组):
对于自己实现深拷贝一般会涉及循环引用
和爆栈
的问题。
对于循环引用:
var a = {
b: b,
c: [1, 2],
d: 1,
e: {
f: {
g: 123
}
}
}
var b = {
a: a,
b: {
c: 123
}
}
a和b其中必有个属性会出现undefined,要么是a中的b,要么是b中的a,看其定义顺序,因此不会出现无限引用的情况。
对于爆栈,可以用尾递归
和循环的方式改写,下面是实现的例子:
对于循环引用来说,我其实觉得并不存在什么问题?
- 使用循环复制的方法来实现
// 都做下尾递归优化处理(转成循环), 防止爆栈
function tco (fn) {
let active = false
let argumentsArr = []
let value
return function () {
if (!active) {
argumentsArr.push(arguments)
while (argumentsArr.length) {
value = fn.apply(this, argumentsArr.shift())
active = true
}
}
active = false
return value
}
}
let _deepClone = tco(function deepclone (obj) { // 防止爆战的深拷贝, 只适合对象和数组的结构
let finObj
if (arguments[1]) {
finObj = arguments[1]
} else {
// console.log('obj,', obj)
if (obj instanceof Array === true) {
finObj = []
} else {
finObj = {}
}
}
for (let i in obj) {
if (typeof obj[i] === 'object') {
finObj[i] = obj[i] instanceof Array ? [] : {}
_deepClone(obj[i], finObj[i])
} else {
finObj[i] = obj[i]
}
}
return finObj
})
var a = {
b: b,
c: [1, 2],
d: 1,
e: {
f: {
g: 123
}
}
}
var b = {
a: a,
b: {
c: 123
}
}
let c = _deepClone(a);
a.c[0] = 2009;
console.log(a)
console.log(c)
输出结果
{ b: undefined, c: [ 2009, 2 ], d: 1, e: { f: { g: 123 } } }
{ b: undefined, c: { '0': 1, '1': 2 }, d: 1, e: { f: { g: 123 } } }
ok,这就是我想要的结果~
- 对于村json格式的对象可以用下面的方式来解决:
var obj = {father: { child: {name: 123}}}
var copy = JSON.parse(JSON.stringify(obj))
(完)
参考文献
https://www.cnblogs.com/echolun/p/7889848.html
https://blog.csdn.net/weixin_37719279/article/details/81240658