上篇文章提到了对象的浅拷贝和深拷贝,当时深拷贝使用的是最简单的方法,如下
JSON.parse(JSON.stringify(obj))
这个方法能实现简单数据的深拷贝,但是对于复杂对象还是有局限性的,比如说会把时间对象转化成字符串,会丢失函数等等。
今天亲自封装一个方法,来实现深拷贝。原理就是先判断数据类型,然后用递归解决嵌套数据。
// 判断数据类型。
function isObject(obj) {
return typeof obj === 'object' && obj != null;
}
// 深拷贝方法
function deepClone(source, hash = new WeakMap()) {
if (!isObject(source)) return source; // 判断是否为基础类型,是的话直接返回
if (hash.has(source)) return hash.get(source); // 查哈希表,解决循环引用和引用丢失的问题。
var target = Array.isArray(source) ? [] : {};
hash.set(source, target); // 哈希表设值(缓存数据)
// Reflect.ownKeys 获取对象自身属性名(包含symbol类型)数组
Reflect.ownKeys(source).forEach(key => {
if (isObject(source[key])) {
target[key] = deepClone(source[key], hash);
} else {
target[key] = source[key];
}
});
return target;
}