我们平时开发中处理前后端数据时会有拷贝数据的情况,今天我们学习下在 JavaScript 中实现拷贝的几种方式。
JSON.parse(JSON.stringify(obj))
const obj = {
a: 1,
b: 'string',
c: true,
d: NaN,
e: Infinity,
f: undefined,
g: null,
h: Symbol('symbol'),
i: new Date('2024-02-05'),
j: new RegExp(/^1/g),
k: {
age: 21,
},
l: function () {
console.log('function');
},
};
const cloneObj = JSON.parse(JSON.stringify(obj));
console.log(cloneObj);
拷贝结果如图,通过上图我们知道这种拷贝的缺点是:
- 会忽略值为 undefined 的属性
- 时间对象的会被转为字符串
- 正则表达式会被转为空对象 {}
- NaN 和 Infinity 会被转为 null
- 无法处理循环引用
Object.assign({}, obj)
const cloneObj = Object.assign({}, obj);
console.log(cloneObj);
Object.assign 拷贝属性不会丢失,但是如果属性是引用类型拷贝之后还是会指向同一个引用
实现一个 deepClone 函数
function deepClone(obj, weakMap = new WeakMap()) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
if (obj instanceof RegExp) {
return new RegExp(obj);
}
if (obj instanceof Date) {
return new Date(obj);
}
if (weakMap.has(obj)) {
return weakMap.get(obj);
}
const clone = Array.isArray(obj) ? [] : {};
for (let key in obj) {
clone[key] = deepClone(obj[key], weakMap);
}
return clone;
}