JSディープクローニングの実装方法

方法 1: オーソドックスなアプローチ(拡張性が高く、推奨)

機能テスト() {

  this.a = 1;

  this.b = 2;

}

test.prototype.c = 3; // プロトタイプのプロパティ

const obj = 新しいテスト();

console.log("元のオブジェクト", obj);

console.log("オブジェクトのクローン", deepClone(obj));

/** JS 深度克隆
 * @param value 需要克隆的值
 */
function deepClone(value) {
  // 排除原始类型的情况,函数时也满足此条件
  if (typeof value !== "object" || value === null) {
    return value;
  }
  // 克隆结果:1.数组 2.普通对象
  const result = Array.isArray(value) ? [] : {};
  // 设置克隆结果的原型链为 value 的原型链(即保持原型一致)
  Object.setPrototypeOf(result, Object.getPrototypeOf(value));
  // 浅层克隆
  for (const key in value) {
    // 排除原型上的属性
    if (value.hasOwnProperty(key)) {
      result[key] = deepClone(value[key]); // 针对这个对象的每一个属性值进行克隆,则达到深度克隆效果
    }
  }
  return result;
}

循環参照の問題を解決する

機能テスト() {

  this.a = 1;

  this.b = 2;

}

test.prototype.c = 3; // プロトタイプのプロパティ

const obj = 新しいテスト();

obj.c = obj; // 循環参照 obj.c は obj 自体と等しい

console.log("元のオブジェクト", obj);

console.log("オブジェクトのクローン", deepClone(obj));

/* 建立缓存区,解决环形引用问题 */
let cache = new WeakMap(); // 使用 WeakMap 为了防止内存泄露

/** JS 深度克隆
 * @param value 需要克隆的值
 */
function deepClone(value) {
  // 排除原始类型的情况,函数时也满足此条件
  if (typeof value !== "object" || value === null) return value;
  // 解决环形引用问题(即循环引用)
  const cached = cache.get(value);
  if (cached) return cached;
  // 克隆结果:1.数组 2.普通对象
  const result = Array.isArray(value) ? [] : {};
  // 设置克隆结果的原型链为 value 的原型链(即保持原型一致)
  Object.setPrototypeOf(result, Object.getPrototypeOf(value));
  // 环形引用时将克隆的值储存到缓存中
  cache.set(value, result);
  // 浅层克隆
  for (const key in value) {
    // 排除原型上的属性
    if (value.hasOwnProperty(key)) {
      result[key] = deepClone(value[key]); // 针对这个对象的每一个属性值进行克隆,则达到深度克隆效果
    }
  }
  return result;
}

方法 2: JSON のシリアル化と逆シリアル化(スケーラビリティなし)

const obj = { id: 1, name: "张三", age: 18 };

const newObj = JSON.parse(JSON.stringify(obj));
newObj.name = "艾凯";
newObj.age = 22;

console.log("obj", obj);
console.log("newObj", newObj);

機能的には問題ありませんが、このアプローチにはいくつかの明らかな欠陥があります。

このオブジェクトに Map などが含まれている場合、クローン作成後、mapList は Map 構造ではなくなります。

または、このオブジェクトにはいくつかの関数があり、これらの関数はクローン作成後に失われます。

const obj = { id: 1, name: "张三", age: 18, mapList: new Map(), fun: function () { } };

const newObj = JSON.parse(JSON.stringify(obj));
newObj.name = "艾凯";
newObj.age = 22;

console.log("obj", obj);
console.log("newObj", newObj);

方法 3: タブページ通信

非同期で時間がかかり、決して使用されない

おすすめ

転載: blog.csdn.net/AdminGuan/article/details/130918249