实现深拷贝
方法一:使用JSON
// 序列化 => 反序列化
const result = JSON.parse(JSON.stringify(data));
缺点:
- 不支持Date、正则、函数等
- 不支持引用
方法二:自己写
手写深拷贝的要点:
- 使用递归
- 判断类型
- 检查环
- 不拷贝原型上的属性
//
const cache = new Map(); // Map的key可以是任意类型,Object的key是string
const deepClone = (data) => {
// 对象
if (data instanceof Object) {
// 检查环
if (cache.has(data)) {
return cache.get(data);
}
let result;
// data是函数
if ( data instanceof Function ) {
// 普通函数
if ( data.prototype ) {
result = function(){return data.apply(this, arguments);};
// 箭头函数
} else {
result = (...args) => data.call(undefined, ...args);
}
// data是数组
} else if (data instanceof Array) {
result = [];
// data是日期
} else if (data instanceof Date) {
result = new Date(data - 0);
// data是正则
} else if (data instanceof RegExp) {
result = new RegExp(data.source, data.flags);
// 其他默认为普通对象,有特殊情况,给上面加判断条件
} else {
result = {};
}
cache.set(data, result);
for(let key in data) {
// 不拷贝原型上的属性
if (data.hasOwnProperty(key)) {
result[key] = deepClone(data[key]);
}
}
return result;
// 基本数据类型
} else {
return data;
}
};
const x = {
arr1: [1, 2, 3],
arr2: [{a: 1}],
fn1: function(a,b) {console.log('普通', a, b);},
fn2: (a, b) => {console.log('箭头', a, b);},
};
function fn1(a, b) {
console.log('普通函数a+b', a + b);
}
const fn2 = (a, b) => {
console.log('箭头函数a-b:', a - b);
}