Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【Q757】如何解决深拷贝问题中的循环引用 #813

Open
shfshanyue opened this issue Apr 14, 2024 · 2 comments
Open

【Q757】如何解决深拷贝问题中的循环引用 #813

shfshanyue opened this issue Apr 14, 2024 · 2 comments
Labels

Comments

@shfshanyue
Copy link
Owner

例:

const o = { a: null }

o.a = o
@shfshanyue shfshanyue added the js label Apr 14, 2024
@echoustintian
Copy link

正常的深拷贝,加一个 Map 记录深拷贝时遍历的属性值,如果两个属性值重复了且这个属性值为引用,那么就不去遍历这个对象的属性

@GrammyLi
Copy link

GrammyLi commented Dec 4, 2024

// 手写深拷贝
const objForDeepClone = {
  num: 1,
  str: "string",
  boo: true,
  nul: null,
  undefined: undefined,
  [Symbol("symbol")]: "symbol", // symbol key
  bigint: BigInt(9007199254740991), // bigint
  arr: [1, 2, 3],
  obj: {
    name: "woow_wu7",
    obj2: { age: 10 },
  },
  fun: function () {
    console.log("this is a function.");
  },
  date: new Date(), // 特殊对象,结构化克隆
  regexp: new RegExp(),
  error: new Error(), // SyntaxError ReferenceError RangeError TypeError URIError EvalError
};
obj.circle = obj; // 循环引用

const deepClone = (obj, map = new Map()) => {
  if (typeof obj !== "object" || obj === null) return obj;

  let res = Array.isArray(obj) ? [] : {};

  if (map.has(obj)) return map.get(obj);
  map.set(obj, res);

  switch (obj.constructor) {
    case RegExp:
    case Error:
    case Date: {
      res = new obj.constructor(obj);
      break;
    }
    default: {
      Reflect.ownKeys(obj).forEach((key) => {
        if (typeof obj[key] === "object") {
          res[key] = deepClone(obj[key], map);
        } else {
          res[key] = obj[key];
        }
      });
    }
  }

  return res;
};

// 调用
const instance = deepClone(objForDeepClone);
console.log("instance1111: ", instance);

// 修改原数据,看是否深拷贝成功
objForDeepClone.num = 1111;
objForDeepClone.str = "strrrrrr";
objForDeepClone.boo = false;
objForDeepClone.arr = [2, 2, 2, 2];
objForDeepClone.obj = {};
objForDeepClone.fun = function () {
  console.log("this is a function2222222.");
};
objForDeepClone.date = new Date(22222);
objForDeepClone.regexp = new RegExp(22222);
objForDeepClone.error = new Error(22222);

console.log("instance2222: ", instance);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants