深入探索JavaScript:精準判斷對象間的“真”相等【含代碼示例】

深入探索JavaScript:精準判斷對象間的“真”相等【含代碼示例】

    • 基本概念與作用說明
      • == 與 === 的區別
      • Object.is()
      • 深度比較的必要性
    • 實戰案例:五種深度比較策略
      • 案例一:樸素遞歸法
      • 案例二:JSON.stringify()法(謹慎使用)
      • 案例三:lodash _.isEqual()
      • 案例四:Reflect.ownKeys()與Proxy的高級組合
      • 案例五:使用WeakMap避免循環引用
    • 不同角度的功能使用思路
    • 實際開發技巧與問題排查
    • 防范漏洞
    • 結論與討論

在JavaScript的世界里,對象比較從來不是一件直截了當的事情。本文將帶你深入探討如何在JS中準確判斷兩個對象是否相等,不僅涵蓋基礎概念,還會通過實戰案例、技巧分享及問題排查,讓你徹底掌握這一核心技能。無論你是前端領域的初學者,還是有一定經驗的開發者,都能在這里找到寶貴的知識點和實戰策略。

基本概念與作用說明

== 與 === 的區別

首先,理解==(寬松相等)和===(嚴格相等)的區別至關重要。===要求兩邊的值和類型完全相同才認為相等,而==則會在比較前進行類型轉換,可能導致意外結果。對于對象來說,無論是==還是===,都只會比較它們的引用是否相同,而非內容是否一致。

Object.is()

雖然不常用,但Object.is()方法提供了一種更精確的比較方式,它在處理NaN+0/-0時表現得更加合理,但對于對象依然只比較引用。

深度比較的必要性

對象的比較往往需要“深度比較”,即比較兩個對象的所有屬性及嵌套對象的值是否一一對應相等,這在處理復雜數據結構時尤為重要。

實戰案例:五種深度比較策略

案例一:樸素遞歸法

function isEqual(obj1, obj2) {// 基礎類型直接比較if (obj1 === obj2 || (Number.isNaN(obj1) && Number.isNaN(obj2))) return true;// 類型或長度不同則不相等if (typeof obj1 !== typeof obj2 || Array.isArray(obj1) !== Array.isArray(obj2)) return false;// 對象或數組進行遞歸比較const keys1 = Object.keys(obj1);const keys2 = Object.keys(obj2);if (keys1.length !== keys2.length) return false;for (const key of keys1) {if (!isEqual(obj1[key], obj2[key])) return false;}return true;
}

案例二:JSON.stringify()法(謹慎使用)

function simpleCompare(obj1, obj2) {return JSON.stringify(obj1) === JSON.stringify(obj2);
}
// 注意:此方法不適用于循環引用的對象,且會丟失函數、undefined等信息。

案例三:lodash _.isEqual()

引入第三方庫lodash,其_.isEqual()方法提供了全面且高效的深度比較。

import _ from 'lodash';
console.log(_.isEqual(object1, object2));

案例四:Reflect.ownKeys()與Proxy的高級組合

適用于需要更精細控制比較邏輯的場景,比如忽略某些屬性或自定義比較規則。

function deepEqualAdvanced(obj1, obj2, options = {}) {const { ignoreKeys = [], customComparers = {} } = options;if (obj1 === obj2) return true;const keys1 = Reflect.ownKeys(obj1);const keys2 = Reflect.ownKeys(obj2);if (keys1.length !== keys2.length) return false;for (const key of keys1) {if (ignoreKeys.includes(key)) continue;const comparer = customComparers[key] || isEqual;if (!comparer(obj1[key], obj2[key])) return false;}return true;
}

案例五:使用WeakMap避免循環引用

針對含有循環引用的對象,可以利用WeakMap來跟蹤已訪問過的對象,避免無限循環。

function deepEqualWithCycles(obj1, obj2, visited = new WeakMap()) {if (obj1 === obj2) return true;if (typeof obj1 !== 'object' || obj1 === null || typeof obj2 !== 'object' || obj2 === null) {return false;}if (visited.has(obj1) && visited.get(obj1) === obj2) return true;visited.set(obj1, obj2);const keys1 = Object.keys(obj1);const keys2 = Object.keys(obj2);if (keys1.length !== keys2.length) return false;for (const key of keys1) {if (!deepEqualWithCycles(obj1[key], obj2[key], visited)) return false;}return true;
}

不同角度的功能使用思路

  • 性能優化:在處理大量數據比較時,考慮提前終止比較或使用更高效的數據結構。
  • 安全性:避免直接使用不可信的輸入進行深度比較,防止潛在的安全風險,如DoS攻擊。

實際開發技巧與問題排查

  • 調試技巧:利用console.log或調試器逐步檢查比較過程,特別是處理復雜對象結構時。
  • 問題排查:遇到比較失敗,檢查是否有未定義屬性、特殊類型的值(如函數、Symbol)或循環引用。
  • 性能考量:在性能敏感的應用中,評估并選擇最合適的比較方法,必要時實現定制化邏輯。

防范漏洞

  • 避免使用eval:在解析字符串為對象進行比較時,絕對不要使用eval,以防注入攻擊。
  • 數據驗證:比較前先驗證輸入數據,確保其格式安全可靠,避免執行惡意代碼。

結論與討論

通過上述探討,我們深入學習了在JavaScript中如何有效地判斷兩個對象是否相等,從基礎概念到高級技巧,從常見方法到安全實踐,每一步都是前端開發者不可或缺的技能。但技術探索永無止境,你是否遇到過特別棘手的對象比較問題?或者有更高效的方法想要分享?歡迎在評論區留下你的見解和經驗,讓我們一起提升前端開發的藝術。


歡迎來到我的博客,很高興能夠在這里和您見面!希望您在這里可以感受到一份輕松愉快的氛圍,不僅可以獲得有趣的內容和知識,也可以暢所欲言、分享您的想法和見解。


推薦:DTcode7的博客首頁。
一個做過前端開發的產品經理,經歷過睿智產品的折磨導致脫發之后,勵志要翻身農奴把歌唱,一邊打入敵人內部一邊持續提升自己,為我們廣大開發同胞謀福祉,堅決抵制睿智產品折磨我們碼農兄弟!


專欄系列(點擊解鎖)學習路線(點擊解鎖)知識定位
《微信小程序相關博客》持續更新中~結合微信官方原生框架、uniapp等小程序框架,記錄請求、封裝、tabbar、UI組件的學習記錄和使用技巧等
《AIGC相關博客》持續更新中~AIGC、AI生產力工具的介紹,例如stable diffusion這種的AI繪畫工具安裝、使用、技巧等總結
《HTML網站開發相關》《前端基礎入門三大核心之html相關博客》前端基礎入門三大核心之html板塊的內容,入坑前端或者輔助學習的必看知識
《前端基礎入門三大核心之JS相關博客》前端JS是JavaScript語言在網頁開發中的應用,負責實現交互效果和動態內容。它與HTML和CSS并稱前端三劍客,共同構建用戶界面。
通過操作DOM元素、響應事件、發起網絡請求等,JS使頁面能夠響應用戶行為,實現數據動態展示和頁面流暢跳轉,是現代Web開發的核心
《前端基礎入門三大核心之CSS相關博客》介紹前端開發中遇到的CSS疑問和各種奇妙的CSS語法,同時收集精美的CSS效果代碼,用來豐富你的web網頁
《canvas繪圖相關博客》Canvas是HTML5中用于繪制圖形的元素,通過JavaScript及其提供的繪圖API,開發者可以在網頁上繪制出各種復雜的圖形、動畫和圖像效果。Canvas提供了高度的靈活性和控制力,使得前端繪圖技術更加豐富和多樣化
《Vue實戰相關博客》持續更新中~詳細總結了常用UI庫elementUI的使用技巧以及Vue的學習之旅
《python相關博客》持續更新中~Python,簡潔易學的編程語言,強大到足以應對各種應用場景,是編程新手的理想選擇,也是專業人士的得力工具
《sql數據庫相關博客》持續更新中~SQL數據庫:高效管理數據的利器,學會SQL,輕松駕馭結構化數據,解鎖數據分析與挖掘的無限可能
《算法系列相關博客》持續更新中~算法與數據結構學習總結,通過JS來編寫處理復雜有趣的算法問題,提升你的技術思維
《IT信息技術相關博客》持續更新中~作為信息化人員所需要掌握的底層技術,涉及軟件開發、網絡建設、系統維護等領域的知識
《信息化人員基礎技能知識相關博客》無論你是開發、產品、實施、經理,只要是從事信息化相關行業的人員,都應該掌握這些信息化的基礎知識,可以不精通但是一定要了解,避免日常工作中貽笑大方
《信息化技能面試寶典相關博客》涉及信息化相關工作基礎知識和面試技巧,提升自我能力與面試通過率,擴展知識面
《前端開發習慣與小技巧相關博客》持續更新中~羅列常用的開發工具使用技巧,如 Vscode快捷鍵操作、Git、CMD、游覽器控制臺等
《photoshop相關博客》持續更新中~基礎的PS學習記錄,含括PPI與DPI、物理像素dp、邏輯像素dip、矢量圖和位圖以及幀動畫等的學習總結
日常開發&辦公&生產【實用工具】分享相關博客》持續更新中~分享介紹各種開發中、工作中、個人生產以及學習上的工具,豐富閱歷,給大家提供處理事情的更多角度,學習了解更多的便利工具,如Fiddler抓包、辦公快捷鍵、虛擬機VMware等工具

吾輩才疏學淺,摹寫之作,恐有瑕疵。望諸君海涵賜教。望輕噴,嚶嚶嚶
非常期待和您一起在這個小小的網絡世界里共同探索、學習和成長。愿斯文對汝有所裨益,縱其簡陋未及淵博,亦足以略盡綿薄之力。倘若尚存闕漏,敬請不吝斧正,俾便精進!

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

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

相關文章

postman教程-6-發送delete請求

領取資料,咨詢答疑,請?wei: June__Go 上一小節我們學習了postman發送put請求的方法,本小節我們講解一下postman發送delete請求的方法。 HTTP DELETE 請求是一種用于刪除指定資源的請求方法。在RESTful API 設計中,DELETE 請求…

tensorboard可視化時save_graph報錯ERROR: Graphs differed across invocations!的一個解決方法

在使用tensorboard可視化,經常會將模型通過save_graph方法保存下來,方便查看結構。在使用save_graph經常會遇到錯誤(至少我經常遇到),對于我,最常見的一個錯誤為 Tracing failed sanity checks! ERROR: Gr…

GPT-4o:重塑人機交互的未來

一個愿意佇立在巨人肩膀上的農民...... 一、推出 在人工智能(AI)領域,自然語言處理(NLP)技術一直被視為連接人類與機器的橋梁。近年來,隨著深度學習技術的快速發展,NLP領域迎來了前所未有的變革…

ARM-V9 RME(Realm Management Extension)系統架構之系統能力的執行隔離

安全之安全(security)博客目錄導讀 目錄 一、執行隔離 1、安全狀態 2、安全模型 本博客探討 RME 所需的系統能力,以保證 Arm CCA 對于 Realms 的安全性和隔離特性。 一、執行隔離 1、安全狀態 RME 系統支持以下安全狀態: 非安全 (Non-secure)安全…

Orange Pi Kunpeng Pro測評

#創作靈感# 參加樹莓派鯤鵬開發版的測評活動,也想體驗一下該開發版,之前有做過樹莓派和香橙派的開發,剛好借此機會了解一下鯤鵬,所以就有了這篇測評文章。 #正文# 引言 說是測評,其實也沒有多少測評方面的內容&…

前端面試題23-34

23. 說說你對 Promise 的理解 Promise 是 ECMAScript6 引入的一種異步編程解決方案,用于處理異步操作。它表示一個尚未完成但最終會結束的操作,具有三種狀態:pending(進行中)、fulfilled(已完成&#xff0…

代碼隨想錄算法訓練營Day22|235.二叉搜索樹的最近公共祖先、701.二叉搜索樹中的插入操作、450.刪除二叉搜索樹中的節點

二叉搜索樹的最近公共祖先 不考慮二叉搜索樹這一條件的話,普通的二叉搜索樹搜索最近的公共祖先就是昨日的做法,這種做法也能解決二叉搜索樹的最近公共祖先。 class Solution { public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, Tr…

貪心算法02(leetcode122/55/4)

參考資料: https://programmercarl.com/0122.%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BAII.html 122. 買賣股票的最佳時機 II 題目描述: 給你一個整數數組 prices ,其中 prices[i] 表示某支股票第…

STM32讀寫內部FLASH讀取芯片id

文章目錄 讀寫內部Flash接線程序編寫測試效果補充 讀取芯片id代碼編寫 讀寫內部Flash 接線 程序編寫 首先使用ThisFlash.c來寫入flash的基本操作,寫入、讀取、擦除,然后使用Store.c配合數組來進行主存與flash的交互 ThisFlash.c #include "stm32…

為什么工控現場會用到Profinet轉Modbus網關設備

一、背景: 工控現場之所以需要使用Profinet轉Modbus網關,是因為工控系統中常常存在不同廠家設備之間通訊協議不一致的問題。而Modbus和Profinet分別代表著兩種不同的通信協議,Profinet通常用于較新的設備,而Modbus則是比較老的通…

思科防火墻ASA Version 9.1(1) 怎么配置靜態NAT,把內網ip192.168.1.10 端口1000映射到公網端口1000上?

環境: 思科防火墻5520 ASA Version 9.1(1) 問題描述: 思科防火墻ASA Version 9.1(1) 怎么配置靜態NAT,把內網ip192.168.1.10 端口1000映射到公網端口1000上? 解決方案: 舊版本8.0 1.做之前要先查一下有沒有端口被占用,要和業務確認2.sh Xlate | in 10011 端口 這條…

ch2應用層--計算機網絡期末復習

2.1應用層協議原理 網絡應用程序位于應用層 開發網絡應用程序: 寫出能夠在不同的端系統上通過網絡彼此通信的程序 2.1.1網絡應用程序體系結構分類: 客戶機/服務器結構 服務器: 總是打開(always-on)具有固定的、眾所周知的IP地址 主機群集常被用于創建強大的虛擬服務器 客…

MongoDB CRUD操作:快照查詢

MongoDB CRUD操作:快照查詢 文章目錄 MongoDB CRUD操作:快照查詢對比本地和快照的讀關注舉例從相同的時間點運行查詢從過去某個時刻讀取數據的一致狀態 配置快照保留時間磁盤空間和歷史記錄 使用快照查詢可以讀取最近某個時間點的數據,而且從…

基于51單片機的溫控風扇的設計–仿真設計

可實現通過DS18B20測量當前環境溫度 可實現通過溫度自動控制風扇轉速 可實現通過按鍵設置不同風速對應的溫度 可實現通過按鍵切換自動、手動模式 可實現在手動模式下通過按鍵調整風扇轉速 可實現通過LCD1602顯示溫度、風扇轉速擋位、自動/手動模式

【C++】模擬實現string類

🦄個人主頁:修修修也 🎏所屬專欄:C ??操作環境:Visual Studio 2022 目錄 一.了解項目功能 二.逐步實現項目功能模塊及其邏輯詳解 🎏構建成員變量 🎏實現string類默認成員函數 📌構造函數 📌析構函數…

k8s 全面掌控日志系統

概述 為了提高系統運維和故障排查的效率, 日志系統采用 ELK(Elasticsearch、Logstash、Kibana)技術棧,通過 FileBeats 作為日志收集器,將來自不同節點的日志數據匯總并存儲在 Elasticsearch 中,最終通過 K…

創建一個新的Spring Security應用程序,并使用JDBC連接數據庫

創建一個新的Spring Security應用程序,并使用JDBC連接數據庫 在這個教程中,我們將學習如何創建一個新的Spring Security應用程序,使用JDBC連接數據庫以獲取用戶信息并進行認證。我們還將學習如何配置Spring Security以從數據庫中獲取用戶和權…

Vue3使用Composition API實現響應式

title: Vue3使用Composition API實現響應式 date: 2024/5/29 下午8:10:24 updated: 2024/5/29 下午8:10:24 categories: 前端開發 tags: Vue3CompositionRefsReactiveWatchLifecycleDebugging 1. 介紹 Composition API是Vue.js 3中新增的一組API,用于在組件中組…

SQL 語言:嵌入式 SQL 和動態 SQL

文章目錄 基本概述嵌入式 SQL動態 SQL總結 基本概述 嵌入式SQL和動態SQL是兩種在應用程序中嵌入和使用SQL語句的方法。它們都允許開發人員在編程語言中編寫SQL語句,以便在應用程序中執行數據庫操作。然而,這兩種方法在實現方式、性能和靈活性方面存在一…

Java數據結構與算法(紅黑樹)

前言 紅黑樹是一種自平衡二叉搜索樹,確保在插入和刪除操作后,樹的高度保持平衡,從而保證基本操作(插入、刪除、查找)的時間復雜度為O(log n)。 實現原理 紅黑樹具有以下性質: 每個節點要么是紅色&#…