js 拷貝-包含處理循環引用問題

在 JavaScript 中,拷貝對象和數組時需要特別注意,因為對象和數組是引用類型,直接賦值只會復制引用,而不是實際的數據。以下是幾種常見的拷貝方法及其應用場景:

1. 淺拷貝(Shallow Copy)

淺拷貝只會復制對象或數組的第一層,而不會遞歸復制其內部的嵌套對象或數組。

1.1 使用 Object.assign

Object.assign 方法用于將所有可枚舉屬性的值從一個或多個源對象復制到目標對象。它只會復制第一層屬性。

const obj1 = { a: 1, b: { c: 2 } };
const obj2 = Object.assign({}, obj1);console.log(obj2); // 輸出:{ a: 1, b: { c: 2 } }
console.log(obj2 === obj1); // 輸出:false
console.log(obj2.b === obj1.b); // 輸出:true 如果是深拷貝,這里應該是false。因為b是引用類型的數據
1.2 使用擴展運算符(Spread Operator)

擴展運算符 ... 可以用于對象和數組,實現淺拷貝。

const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { ...obj1 };console.log(obj2); // 輸出:{ a: 1, b: { c: 2 } }
console.log(obj2 === obj1); // 輸出:false
console.log(obj2.b === obj1.b); // 輸出:true
1.3 使用 Array.prototype.slice 和擴展運算符

對于數組,可以使用 slice 和擴展運算符實現淺拷貝。

const arr1 = [1, 2, [3, 4]];
const arr2 = [...arr1];console.log(arr2); // 輸出:[1, 2, [3, 4]]
console.log(arr2 === arr1); // 輸出:false
console.log(arr2[2] === arr1[2]); // 輸出:true

2. 深拷貝(Deep Copy)

深拷貝會遞歸復制對象或數組的所有層級,包括嵌套的對象和數組。

2.1 使用 JSON.parseJSON.stringify

JSON.parseJSON.stringify 可以實現簡單的深拷貝,但只適用于不含函數、undefinedDate 等特殊類型的對象,并且他也無法處理循環引用的問題。

const obj1 = { a: 1, b: { c: 2 } };
const obj2 = JSON.parse(JSON.stringify(obj1));console.log(obj2); // 輸出:{ a: 1, b: { c: 2 } }
console.log(obj2 === obj1); // 輸出:false
console.log(obj2.b === obj1.b); // 輸出:false
2.2 使用遞歸函數

可以編寫一個遞歸函數來實現深拷貝。并且也可以解決循環引用的問題

function deepClone(objValue) {// 定義一個緩存的mapconst cache = new WeakMap() // 為什么用WeakMap 而不用Map,因為WeakMap 可以垃圾回收function _deepClone(obj) {//  判斷是否是非對象類型(即基本數據類型)if (obj === null || (obj instanceof Object === false)) {return obj;}if (cache.has(obj)) {// 新增代碼,查哈希表return cache.get(obj)}let target = Array.isArray(obj) ? [] : {}cache.set(obj, target)// 哈希表設值for (let i in obj) {// 判斷是否是自身屬性,而不是繼承來的屬性if (obj.hasOwnProperty(i)) {if (obj[i] instanceof Object === true) {// 判斷是不是引用類型target[i] = _deepClone(obj[i])} else {target[i] = obj[i]}}}return target;}return _deepClone(objValue)
}
const obj1 = { a: 1, arr:[1,2,3] };
obj1.sub=obj1
obj1.arr.push(obj1)
const newObj= deepClone(obj1);console.log(newObj.arr!==obj1.arr); // true
console.log(newObj.sub!== obj1.sub); // true
console.log(newObj.arr[3]!== obj1); // true
console.log(newObj.arr[3]=== newObj); // true

3. 使用第三方庫

3.1 使用 Lodash 的 _.cloneDeep

Lodash 是一個功能豐富的 JavaScript 實用工具庫,提供了 _.cloneDeep 方法來實現深拷貝。

import _ from 'lodash';const obj1 = { a: 1, b: { c: 2 } };
const obj2 = _.cloneDeep(obj1);console.log(obj2); // 輸出:{ a: 1, b: { c: 2 } }
console.log(obj2 === obj1); // 輸出:false
console.log(obj2.b === obj1.b); // 輸出:false

總結

  • 淺拷貝:適用于不需要遞歸復制嵌套對象或數組的場景。

    • Object.assign
    • 擴展運算符 ...
    • Array.prototype.slice 和擴展運算符
  • 深拷貝:適用于需要遞歸復制嵌套對象或數組的場景。

    • JSON.parseJSON.stringify(不支持特殊類型)
    • 遞歸函數
    • 第三方庫(如 Lodash 的 _.cloneDeep

根據實際需求選擇合適的拷貝方法,可以高效地實現對象和數組的拷貝。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/76301.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/76301.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/76301.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

oracle將varchar2 轉為clob類型存儲。 oracle不支持直接使用sql,將 varchar2 到clob的類型轉換,需要下面操作

將一個現有表中的 VARCHAR2 列數據遷移到一個 CLOB 列的過程。以下是對每一步操作的說明: 1. 添加一個新的 CLOB 類型列 首先,向表中添加一個新的 CLOB 類型的列。這個列將用來存儲原本的 VARCHAR2 數據。 ALTER TABLE your_table ADD (new_column CL…

Dynamics 365 Business Central Recurring Sales Lines 經常購買銷售行 來作 訂閱

#D365 BC ERP# #Navision# 前面有節文章專門介紹了BC 2024 Wave 2 支持的更好的Substription & Recurring Billing。 其實在D365 BC ERP中一直有一個比較簡單的訂閱模塊Recrring Sales Lines。本文將介紹一下如何用Recurring Sales Lines來 實施簡易的訂閱Substription。具…

算法比賽中常用的數學知識

一、求某個整數的正約數個數與正約數之和 1.1求某個正整數N的正約數個數 public class Main {public static void main(String[] args) {System.out.println(count(360));//結果為24}public static long count(long number){long count1;for(long i2;i<Math.sqrt(number);…

虛擬Ubuntu系統 開機提示:SMBus Host controller not enabled 后正常啟動,去除這個提示提升開機速度。

如題&#xff0c;虛擬機中的Ubuntu系統開機提示&#xff1a;SMBus Host controller not enabled&#xff0c;雖然能正常啟動&#xff0c;但不僅影響開機速度&#xff0c;而且還膈應人。 使用命令查看模塊 lsmod | grep piix4 發現i2c_piix4有問題&#xff0c; 禁止 i2c_piix4…

NLP基礎知識 與 詞向量的轉化方法 發展

目錄 1.NLP 基礎知識點 為什么需要自然語言處理? 自然語言處理有哪些分類? 自然語言處理有哪些實際應用? 為什么需要自然語言處理? 自然語言處理有哪些分類? 自然語言處理有哪些實際應用? 自然語言處理的技術/工作原理是什么? 2.NLP文本轉化為詞向量的方法 2…

【FPGA基礎學習】狀態機思想實現流水燈

目錄 一、用狀態機實現LED流水燈1.狀態機思想簡介1. 1基本概念1.2.核心要素1.3分類與模型 2.LED流水燈 二、CPLD與FPGA1.技術區別2.應用場景3.設計選擇建議 三、HDLbits組合邏輯題目 一、用狀態機實現LED流水燈 1.狀態機思想簡介 1. 1基本概念 ? 狀態機&#xff08;Finite …

CSS語言的游戲AI

CSS語言的游戲AI探討 隨著技術的飛速發展&#xff0c;游戲行業也在不斷地革命和演變。游戲中的人工智能&#xff08;AI&#xff09;作為一種重要的設計元素&#xff0c;其復雜性和智能程度對游戲的體驗、玩法和整體表現都有著深遠的影響。近年來&#xff0c;CSS&#xff08;Ca…

docker配置redis容器時配置文件docker-compose.yml示例

1.配置數據節點&#xff08;主從節點&#xff09; version: 3.7 services:master:image: redis:5.0.9container_name: redis-masterrestart: alwayscommand: redis-server --appendonly yesports:- 6379:6379slave1:image: redis:5.0.9container_name: redis-slave1restart: a…

【WPF】IOC控制反轉的應用:彈窗但不互相調用ViewModel

全稱&#xff1a;Inversion of Control&#xff0c;控制反轉 場景&#xff1a;A頁面需要調用B/C頁面等&#xff0c;防止直接在VM中新建別的頁面實例&#xff0c;使用IOC設計架構&#xff1b; 創建Service&#xff0c;在Service中實現頁面的實例創建和定義頁面輸入輸出參數。 在…

MySQL學習筆記十五

第十七章組合查詢 17.1組合查詢 MySQL允許執行多個查詢&#xff08;多條SELECT語句&#xff09;&#xff0c;并將結果作為單個查詢結果集返回。這些組合查詢通常稱為并&#xff08;union&#xff09;或復合查詢&#xff08;compound query&#xff09;。 以下幾種情況需要使…

【MySQL】安裝

下載 MySQL :: MySQL Downloads 安裝 mysql 驗證

ffpyplayer+Qt,制作一個視頻播放器

ffpyplayerQt&#xff0c;制作一個視頻播放器 項目地址FFmpegMediaPlayerVideoWidget 項目地址 https://gitee.com/chiyaun/QtFFMediaPlayer FFmpegMediaPlayer 按照 QMediaPlayer的方法重寫一個ffpyplayer # coding:utf-8 import logging from typing import Unionfrom PySide…

Spring Boot 國際化配置項詳解

Spring Boot 國際化配置項詳解 1. 核心配置項分類 將配置項分為以下類別&#xff0c;便于快速定位&#xff1a; 1.1 消息源配置&#xff08;MessageSource 相關&#xff09; 控制屬性文件的加載、編碼、緩存等行為。 配置項作用默認值示例說明spring.messages.basename指定屬…

拍攝的婚慶視頻有些DAT的視頻文件打不開怎么辦

3-12 現在的婚慶公司大多提供結婚的拍攝服務&#xff0c;或者有一些第三方公司做這方面業務&#xff0c;對于視頻拍攝來說&#xff0c;有時候會遇到這樣一種問題&#xff0c;就是拍攝下來的視頻文件&#xff0c;然后會有一兩個視頻文件是損壞的&#xff0c;播放不了&#xff0…

【力扣hot100題】(073)數組中的第K個最大元素

花了兩天時間搞明白答案的快速排序和堆排序。 兩種都寫了一遍&#xff0c;感覺堆排序更簡單很多。 兩種都記錄一下&#xff0c;包括具體方法和易錯點。 快速排序 class Solution { public:vector<int> nums;int quicksort(int left,int right,int k){if(leftright) r…

【親測】Linux 使用 Matplotlib 顯示中文

文章目錄 安裝中文字體在Matplotlib中使用該字體來顯示中文 在 Linux 系統中使用 Matplotlib 繪制圖表時&#xff0c;如果需要顯示中文&#xff0c;可能會遇到中文字符顯示為方塊或者亂碼的問題。這是因為Matplotlib 默認使用的字體不支持中文。本文手把手帶你解決這個問題。 …

Redis Java 客戶端 之 SpringDataRedis

SpringDataRedis SpringData是Spring中數據操作的模塊&#xff0c;包含對各種數據庫的集成&#xff0c;其中對Redis集成模塊就叫做SpringDataRedis&#xff0c; 官方地址&#xff1a;https://spring.io/projects/spring-data-redis 特性&#xff1a; 提供了對不同Redis客戶端…

數字化轉型:重構生存邏輯,不止系統升級

數字化轉型不過是升級系統&#xff0c;砸了錢、耗了力&#xff0c;卻沒達到預期&#xff0c;競爭力也沒提升。實際上&#xff0c;數字化轉型是對企業生存邏輯的徹~底重構&#xff0c;關乎商業模式、運營流程等方方面面。? 很多企業覺得數字化轉型是 IT 部門的事&#xff0c;只…

C語言隊列的實現

目錄 ?編輯 &#xff08;一&#xff09;隊列的定義,初始化及創建結點 &#xff08;二&#xff09;入隊和出隊&#xff0c;以及取隊頭隊尾的數據 (三)銷毀隊列 隊列是指只允許在一端進行插入數據操作&#xff0c;在另?端進行刪除數據操作的特殊線性表&#xff0c;隊列具有先…

mapbox進階,使用本地dem數據,加載hillshade山體陰影圖層

????? 主頁: gis分享者 ????? 感謝各位大佬 點贊?? 收藏? 留言?? 加關注?! ????? 收錄于專欄:mapbox 從入門到精通 文章目錄 一、??前言1.1 ??mapboxgl.Map 地圖對象1.2 ??mapboxgl.Map style屬性1.3 ??hillshade 山體陰影圖層 api1.3.1 ??…