背景

深拷贝与浅拷贝

徐徐
前端
发表于 2024-08-20 16:33:43
🌺 摘要
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
作者:徐徐
转载请注明出处
上一篇:前端拨号的方法
下一篇:判断js类型