浅拷贝与深拷贝区别
浅拷贝
对于浅拷贝而言,就是只拷贝对象的引用,而不深层次的拷贝对象的值,多个对象指向堆内存中的同一对象,任何一个修改都会使得所有对象的值修改,因为它们公用一条数据
深拷贝
深拷贝不会拷贝引用类型的引用,而是将引用类型的值全部拷贝一份,形成一个新的引用类型,这样就不会发生引用错乱的问题,使得我们可以多次使用同样的数据,而不用担心数据之间会起冲突
深拷贝的实现
1、最简单的深拷贝——JSON.stringify()以及JSON.parse()
var obj1 = {
a: 1,
b: 2,
c: 3
}
var objString = JSON.stringify(obj1);
var obj2 = JSON.parse(objString);
obj2.a = 4;
console.log(obj1.a); // 1
console.log(obj2.a); // 4
可以看到没有发生引用问题,修改obj2的数据,并不会对obj1造成任何影响
JSON.stringify()以及JSON.parse()它是不可以拷贝 undefined , function, RegExp 等等类型的。
2、第二种方式 Object.assign(target, source)
var obj1 = {
a: 1,
b: 2,
c: 3
}
var obj2 = Object.assign({}, obj1);
obj2.b = 4;
console.log(obj1.b); // 2
console.log(obj2.b); // 4
可以看到对于一层对象来说是没有任何问题的,但是如果对象的属性对应的是其它的引用类型的话,还是只拷贝了引用,修改的话还是会有问题
3、第三种方式 递归拷贝
function deppClone (target) {
let result
//
if (Object.prototype.toString.call(target) === "[object Object]") {
// 如果是数组
if (Array.isArray(target)) {
result = []
for (let i in target) {
result.push(deepClone(target[i]))
}
// 如果为空null
} else if (target === null) {
result = null
// 如果为RegExp对象
} else if (target.constructor === RegExp) {
result = target
} else { // 否则普通对象
result = {}
for (let i in target) {
result[i] = deepClone(target[i])
}
}
} else { //否则为基本数据类型
result = target
}
return result
}
最终在这里弥补了第一种方法的不足
站在巨人的肩膀上,每天进步一点!