深浅拷贝区别:
对于简单的数据类型,如数字、字符串或布尔值,浅拷贝和深拷贝没有什么区别,但对于复杂数据类型,浅拷贝只复制对象本身以及其内部引用的地址(即指针),而不复制引用指向的对象。因此,如果原始对象中的某个对象发生更改,那么在浅拷贝对象中也会发生相应的更改。
深拷贝则会递归地复制对象本身以及其引用的对象,因此原始对象和复制后的对象互相独立,修改一个对象不会影响另一个对象。
下面看下实现方式:
// 深拷贝
function deepCopy(obj, hash = new WeakMap) {
// 如果是Date、RegExp 通过new方式返回一个新的对象
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
// 如果是空或者基础类型,直接返回即可
if (obj === null || typeof obj !== 'object')
return obj;
// 如果备忘中已经存在,则返回备忘录中的数据,防止无线递归的问题
if (hash.has(obj)) return hash.get(obj);
// 这里主要是为了继承原型上的东西
const temp = new obj.constructor();
// 设置备忘录
hash.set(obj, temp);
for (let key in obj) {
// 这里只处理自身的属性,继承属性则通过new constructor实现
if (obj.hasOwnProperty) {
temp[key] = deepClone(obj[key], hash);
}
}
return temp;
}
// 浅拷贝
function lightCopy(obj) {
// 如果不是对象类型,则直接返回
if (!obj || typeof obj !== 'object') {
return obj;
}
// 返回浅拷贝后的对象
return Object.assign({}, obj);
}
// 验证
var a = { info: { name: 'Mark' } };
// var b = lightCopy(a);
var b = deepCopy(a);
a.info.name = 'JSON';
var str = 'test';
console.log('验证值类型', lightCopy(str) === deepCopy(str), deepCopy(str)) // true 'test'
console.log('验证引用类型', a, b); // 浅拷贝:a { info: { name: 'JSON' } } b { info: { name: 'JSON' } }
//深拷贝:a { info: { name: 'JSON' } } b { info: { name: 'Mark' } }