🌺
摘要
js深拷贝与浅拷贝
什么是深拷贝和浅拷贝?
深拷贝和浅拷贝是针对js对象和数组的拷贝来说的 根本原因是对象或者数组的属性值是一个引用类型,那么该属性值存储的是一个引用地址指向存放对象的堆中,所以把属性值拷贝后,只是把地址值拷贝过去,导致原对象和拷贝对象的属性值指向了同一个堆位置,修改其中一个属性值的内部属性,拷贝对象会跟着修改,这就是浅拷贝,所以要深拷贝对象需要以下方法
深拷贝
1.递归自定义深拷贝
function clone(obj) {
if (typeof obj !== "object" || obj === null) return obj;
var newObj = obj instanceof Array ? [] : {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = typeof obj[key] === "object" ? clone(obj[key]) : obj[key];
}
}
return newObj;
}
2.使用JSON.stringify和JSON.parse方法
先把对象使用JSON.stringify转换为字符串,再JSON.parse解析字符串生成一个新对象
缺点:
- 无法处理 undefined、function、Date、Map、Set、RegExp 等复杂类型
- 无法处理循环引用
3.structuredClone()(现代浏览器)
这是原生的js api
const obj1 = { a: 1, b: { c: 2 }, d: new Date() };
const obj2 = structuredClone(obj1);
obj2.b.c = 3;
console.log(obj1.b.c); // 2,原对象不受影响
console.log(obj2.b.c); // 3
console.log(obj1.d instanceof Date); // true,Date 被正确复制
4.使用 MessageChannel(适用于特殊场景)
function deepClone(obj) {
return new Promise((resolve) => {
const { port1, port2 } = new MessageChannel();
port2.onmessage = (ev) => resolve(ev.data);
port1.postMessage(obj);
});
}
const obj = { a: 1, b: { c: 2 } };
deepClone(obj).then((deepCopy) => {
console.log(deepCopy); // { a: 1, b: { c: 2 } }
});
5.Lodash 的 cloneDeep
import _ from "lodash";
const obj = { a: 1, b: { c: 2 } };
const deepCopy = _.cloneDeep(obj);
console.log(deepCopy); // { a: 1, b: { c: 2 } }
浅拷贝
1. Object.assign()
2. 扩展运算符
文章发表于 2024-08-20 16:33:43
作者:徐徐转载请注明出处