再见`JSON.stringify()`和`{...obj}`,你好`structuredClone()`!

2025-06-11

再见`JSON.stringify()`和`{...obj}`,你好`structuredClone()`!

  • 什么是structuredClone()

    • structuredClone()是 2022 年引入的全局函数,支持 JavaScript 对象的深度克隆。与JSON.stringify()和 等传统方法不同JSON.parse(),它们难以应对复杂的结构和循环引用,而structuredClone()可以轻松应对这些挑战。
  • 为什么它会改变游戏规则?

    • 它是一款强大的工具,可用于创建真正的深度克隆,无需额外的逻辑或变通方法即可保留嵌套对象和循环引用的完整性。此外,它还适用于现代环境,包括 Web Workers。

1. 简单对象克隆:基础知识

  • 使用{...obj}(浅拷贝)
  const original = { name: "Alice", details: { age: 25 } };
  const shallowCopy = { ...original };

  shallowCopy.details.age = 30;

  console.log(original.details.age); // 30
  console.log(shallowCopy.details.age); // 30
Enter fullscreen mode Exit fullscreen mode
  • 发生什么事了?

    • 扩展运算符{...obj}仅创建浅拷贝。details对象没有被深度克隆,因此更改也会shallowCopy.details影响原始对象details
    • 使用JSON.stringify()+ JSON.parse()(深层复制)
  const original = { name: "Alice", details: { age: 25 } };
  const deepCopy = JSON.parse(JSON.stringify(original));

  deepCopy.details.age = 30;

  console.log(original.details.age); // 25
  console.log(deepCopy.details.age); // 30
Enter fullscreen mode Exit fullscreen mode
  • 发生什么事了?

    • 此方法创建深层复制,但有局限性:它不能处理函数undefined或循环引用。
    • 使用structuredClone()(深层复制)
  const original = { name: "Alice", details: { age: 25 } };
  const clone = structuredClone(original);

  clone.details.age = 30;

  console.log(original.details.age); // 25
  console.log(clone.details.age); // 30
Enter fullscreen mode Exit fullscreen mode
  • 发生什么事了?
    • structuredClone()创建深度克隆,保留结构而不受任何限制JSON.stringify(),并处理复杂数据类型,如循环引用和undefined

2. 处理循环引用:一个挑战

  • 循环引用{...obj}
  const original = { name: "Alice" };
  original.self = original;

  // This will cause an error:
  const shallowCopy = { ...original }; // TypeError: Converting circular structure to JSON
Enter fullscreen mode Exit fullscreen mode
  • 发生什么事了?

    • {...obj}无法处理循环引用,导致错误。
    • 循环引用JSON.stringify()
  const original = { name: "Alice" };
  original.self = original;

  // This will cause an error:
  const jsonCopy = JSON.parse(JSON.stringify(original)); // TypeError: Converting circular structure to JSON
Enter fullscreen mode Exit fullscreen mode
  • 发生什么事了?

    • JSON.stringify()循环引用也会失败,引发错误。
    • 循环引用structuredClone()
  const original = { name: "Alice" };
  original.self = original;

  const clone = structuredClone(original);

  console.log(clone !== original); // true
  console.log(clone.self === clone); // true
Enter fullscreen mode Exit fullscreen mode
  • 发生什么事了?
    • structuredClone()无缝处理循环引用,创建适当的深度克隆而不会出现错误。

3. 使用函数进行克隆undefined:另一个测试

  • 使用{...obj}
  const original = { name: "Alice", greet: () => "Hello!", value: undefined };
  const shallowCopy = { ...original };

  console.log(shallowCopy.greet()); // "Hello!"
  console.log(shallowCopy.value); // undefined
Enter fullscreen mode Exit fullscreen mode
  • 发生什么事了?

    • {...obj}复制函数并按undefined预期进行,但只是浅显的。
    • 使用JSON.stringify()
  const original = { name: "Alice", greet: () => "Hello!", value: undefined };
  const jsonCopy = JSON.parse(JSON.stringify(original));

  console.log(jsonCopy.greet); // undefined
  console.log(jsonCopy.value); // undefined
Enter fullscreen mode Exit fullscreen mode
  • 发生什么事了?

    • JSON.stringify()无法序列化函数或undefined,导致它们在克隆对象中丢失。
    • 使用structuredClone()
  const original = { name: "Alice", greet: () => "Hello!", value: undefined };
  const clone = structuredClone(original);

  console.log(clone.greet); // undefined
  console.log(clone.value); // undefined
Enter fullscreen mode Exit fullscreen mode
  • 发生什么事了?
    • structuredClone()也不会克隆函数但会保留值,这使得它比复杂对象undefined更可靠。JSON.stringify()

4. 速度与效率:性能说明

  • 大数据效率
  const largeArray = new Array(1e6).fill({ key: "value" });

  console.time("structuredClone");
  const clone = structuredClone(largeArray);
  console.timeEnd("structuredClone");

  console.time("JSON.stringify + JSON.parse");
  const jsonCopy = JSON.parse(JSON.stringify(largeArray));
  console.timeEnd("JSON.stringify + JSON.parse");
Enter fullscreen mode Exit fullscreen mode
  • 发生什么事了?
    • structuredClone()对于大型复杂数据来说,通常比JSON.stringify()+更快JSON.parse(),并且避免了序列化和反序列化的陷阱。

5. 结论:structuredClone()未来为何

  • 可靠性undefined:更可预测地处理循环引用、函数和值。
  • 效率:对大型数据集执行深度克隆的速度更快,并且不需要变通方法。
  • 简单:一种方法即可解决所有问题 — — 不再需要在、或自定义深度克隆函数之间进行{...obj}选择JSON.stringify()
鏂囩珷鏉ユ簮锛�https://dev.to/dharamgfx/bye-bye-jsonstringify-and-obj-hello-structuredclone-2e4c
PREV
CSS 或 JS 中的简单过滤器
NEXT
🔥12 款最佳开发者 AI 编码辅助工具🧑‍💻