」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 再見`JSON.stringify()`和`{...obj}`,你好`structedClone()`!

再見`JSON.stringify()`和`{...obj}`,你好`structedClone()`!

發佈於2024-11-08
瀏覽:326

Bye-Bye `JSON.stringify()` and `{...obj}`, Hello `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
  • 發生了什麼事?

    • 擴充運算子 {...obj} 僅建立淺拷貝。詳細資訊物件沒有被深度克隆,因此對shallowCopy.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
  • 發生了什麼事?

    • 此方法建立深層複製,但有其限制:它無法處理函數、未定義或循環引用。
    • 使用 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
  • 發生了什麼事?
    • StructuredClone() 建立深度克隆,保留結構,不受 JSON.stringify() 的任何限制,並處理複雜的資料類型,如循環引用和未定義。

2.處理循環引用:一個挑戰

  • 帶有 {...obj} 的循環引用
  const original = { name: "Alice" };
  original.self = original;

  // This will cause an error:
  const shallowCopy = { ...original }; // TypeError: Converting circular structure to JSON
  • 發生了什麼事?

    • {...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
  • 發生了什麼事?

    • 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
  • 發生了什麼事?
    • StructuredClone() 無縫處理循環引用,創建正確的深度克隆而不會出現錯誤。

3.使用函數和未定義進行克隆:另一個測試

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

  console.log(shallowCopy.greet()); // "Hello!"
  console.log(shallowCopy.value); // undefined
  • 發生了什麼事?

    • {...obj} 複製函數並如預期未定義,但只是淺層。
    • 使用 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
  • 發生了什麼事?

    • JSON.stringify() 無法序列化函數或未定義,導致它們在複製物件中遺失。
    • 使用 StructuredClone()
  const original = { name: "Alice", greet: () => "Hello!", value: undefined };
  const clone = structuredClone(original);

  console.log(clone.greet); // undefined
  console.log(clone.value); // undefined
  • 發生了什麼事?
    • StructuredClone() 也不會複製函數,但會保留未定義的值,這使得它對於複雜物件比 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");
  • 發生了什麼事?
    • 對於大型、複雜的數據, StructuredClone() 通常比 JSON.stringify() JSON.parse() 更快,並且避免了序列化和反序列化的陷阱。

5.結論:為什麼 StructuredClone() 是未來

  • 可靠性:更可預測地處理循環引用、函數和未定義值。
  • 效率:對大型資料集更快執行深度克隆,且不需要解決方法。
  • 簡單:統治所有這些的方法 - 不再需要在 {...obj}、JSON.stringify() 或自訂深度克隆函數之間進行選擇。
版本聲明 本文轉載於:https://dev.to/dharamgfx/bye-bye-jsonstringify-and-obj-hello-structuredclone-2e4c?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何處理PHP文件系統功能中的UTF-8文件名?
    如何處理PHP文件系統功能中的UTF-8文件名?
    在PHP的Filesystem functions中處理UTF-8 FileNames 在使用PHP的MKDIR函數中含有UTF-8字符的文件很多flusf-8字符時,您可能會在Windows Explorer中遇到comploreer grounder grounder grounder gro...
    程式設計 發佈於2025-04-22
  • CSS強類型語言解析
    CSS強類型語言解析
    您可以通过其强度或弱输入的方式对编程语言进行分类的方式之一。在这里,“键入”意味着是否在编译时已知变量。一个例子是一个场景,将整数(1)添加到包含整数(“ 1”)的字符串: result = 1 "1";包含整数的字符串可能是由带有许多运动部件的复杂逻辑套件无意间生成的。它也可以是故意从单个真理...
    程式設計 發佈於2025-04-22
  • Java數組中元素位置查找技巧
    Java數組中元素位置查找技巧
    在Java數組中檢索元素的位置 利用Java的反射API將數組轉換為列表中,允許您使用indexof方法。 (primitives)(鏈接到Mishax的解決方案) 用於排序陣列的數組此方法此方法返回元素的索引,如果發現了元素的索引,或一個負值,指示應放置元素的插入點。
    程式設計 發佈於2025-04-22
  • 為什麼使用Firefox後退按鈕時JavaScript執行停止?
    為什麼使用Firefox後退按鈕時JavaScript執行停止?
    導航歷史記錄問題:JavaScript使用Firefox Back Back 此行為是由瀏覽器緩存JavaScript資源引起的。要解決此問題並確保在後續頁面訪問中執行腳本,Firefox用戶應設置一個空功能。 警報'); }; alert('inline Alert')...
    程式設計 發佈於2025-04-22
  • 如何使用組在MySQL中旋轉數據?
    如何使用組在MySQL中旋轉數據?
    在關係數據庫中使用mySQL組使用mySQL組進行查詢結果,在關係數據庫中使用MySQL組,轉移數據的數據是指重新排列的行和列的重排以增強數據可視化。在這裡,我們面對一個共同的挑戰:使用組的組將數據從基於行的基於列的轉換為基於列。 Let's consider the following ...
    程式設計 發佈於2025-04-22
  • Java中Lambda表達式為何需要“final”或“有效final”變量?
    Java中Lambda表達式為何需要“final”或“有效final”變量?
    Lambda Expressions Require "Final" or "Effectively Final" VariablesThe error message "Variable used in lambda expression shou...
    程式設計 發佈於2025-04-22
  • 如何在JavaScript對像中動態設置鍵?
    如何在JavaScript對像中動態設置鍵?
    在嘗試為JavaScript對象創建動態鍵時,如何使用此Syntax jsObj['key' i] = 'example' 1;不工作。正確的方法採用方括號: jsobj ['key''i] ='example'1; 在JavaScript中,數組是一...
    程式設計 發佈於2025-04-22
  • 為什麼不````''{margin:0; }`始終刪除CSS中的最高邊距?
    為什麼不````''{margin:0; }`始終刪除CSS中的最高邊距?
    在CSS 問題:不正確的代碼: 全球範圍將所有餘量重置為零,如提供的代碼所建議的,可能會導致意外的副作用。解決特定的保證金問題是更建議的。 例如,在提供的示例中,將以下代碼添加到CSS中,將解決餘量問題: body H1 { 保證金頂:-40px; } 此方法更精確,避免了由全局保證金重置...
    程式設計 發佈於2025-04-22
  • 如何有效地選擇熊貓數據框中的列?
    如何有效地選擇熊貓數據框中的列?
    在處理數據操作任務時,在Pandas DataFrames 中選擇列時,選擇特定列的必要條件是必要的。在Pandas中,選擇列的各種選項。 選項1:使用列名 如果已知列索引,請使用ILOC函數選擇它們。請注意,python索引基於零。 df1 = df.iloc [:,0:2]#使用索引0和1 ...
    程式設計 發佈於2025-04-22
  • 版本5.6.5之前,使用current_timestamp與時間戳列的current_timestamp與時間戳列有什麼限制?
    版本5.6.5之前,使用current_timestamp與時間戳列的current_timestamp與時間戳列有什麼限制?
    在時間戳列上使用current_timestamp或MySQL版本中的current_timestamp或在5.6.5 此限制源於遺留實現的關注,這些限制需要對當前的_timestamp功能進行特定的實現。 創建表`foo`( `Productid` int(10)unsigned not ...
    程式設計 發佈於2025-04-22
  • C++20 Consteval函數中模板參數能否依賴於函數參數?
    C++20 Consteval函數中模板參數能否依賴於函數參數?
    [ consteval函數和模板參數依賴於函數參數在C 17中,模板參數不能依賴一個函數參數,因為編譯器仍然需要對非contexexpr futcoriations contim at contexpr function進行評估。 compile time。 C 20引入恆定函數,必須在編譯時進...
    程式設計 發佈於2025-04-22
  • 找到最大計數時,如何解決mySQL中的“組函數\”錯誤的“無效使用”?
    找到最大計數時,如何解決mySQL中的“組函數\”錯誤的“無效使用”?
    如何在mySQL中使用mySql 檢索最大計數,您可能會遇到一個問題,您可能會在嘗試使用以下命令:理解錯誤正確找到由名稱列分組的值的最大計數,請使用以下修改後的查詢: 計數(*)為c 來自EMP1 按名稱組 c desc訂購 限制1 查詢說明 select語句提取名稱列和每個名稱...
    程式設計 發佈於2025-04-22
  • 如何在Java中正確顯示“ DD/MM/YYYY HH:MM:SS.SS”格式的當前日期和時間?
    如何在Java中正確顯示“ DD/MM/YYYY HH:MM:SS.SS”格式的當前日期和時間?
    如何在“ dd/mm/yyyy hh:mm:mm:ss.ss”格式“ gormat 解決方案:的,請訪問量很大,並應為procectiquiestate的,並在整個代碼上正確格式不多: java.text.simpledateformat; 導入java.util.calendar; 導入java...
    程式設計 發佈於2025-04-22
  • 反射動態實現Go接口用於RPC方法探索
    反射動態實現Go接口用於RPC方法探索
    在GO 使用反射來實現定義RPC式方法的界面。例如,考慮一個接口,例如:鍵入myService接口{ 登錄(用戶名,密碼字符串)(sessionId int,錯誤錯誤) helloworld(sessionid int)(hi String,錯誤錯誤) } 替代方案而不是依靠反射...
    程式設計 發佈於2025-04-22
  • 如何同步迭代並從PHP中的兩個等級陣列打印值?
    如何同步迭代並從PHP中的兩個等級陣列打印值?
    同步的迭代和打印值來自相同大小的兩個數組使用兩個數組相等大小的selectbox時,一個包含country代碼的數組,另一個包含鄉村代碼,另一個包含其相應名稱的數組,可能會因不當提供了exply for for for the uncore for the forsion for for ytry...
    程式設計 發佈於2025-04-22

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3