摘要:原文出處相等是中起初最讓人困惑的部分。和的比較強制類型的順序等等,都使得這個問題變得復雜。依據引用的判斷會檢查所給的是否指向內存中的相同地址。
原文出處:Object Equality in JavaScript
相等是JavaScript中起初最讓人困惑的部分。==和===的比較、強制類型的順序等等,都使得這個問題變得復雜。今天,我們會聚焦另一個方面:object相等是如何實現的。
你也許認為,如果兩個object有相同的屬性并且它們多有的屬性值都相同,那么這兩個object應該是相等的。我們來看看是否如我們所料:
var jangoFett = { occupation: "Bounty Hunter", genetics: "superb" }; var bobaFett = { occupation: "Bounty Hunter", genetics: "superb" }; // Outputs: false console.log(bobaFett === jangoFett);
bobaFett和jangoFett的屬性完全相同,但是兩個object并不認為是相等的。難道是我們使用恒等運算符的原因?我們來驗證下:
// Outputs: false console.log(bobaFett == jangoFett);
我們這樣做,是因為JavaScript內部其實有兩套不同的方案來驗證相等(譯者加:ecma規范中定義的[The Strict Equality Comparison Algorithm
](http://www.ecma-international...)。像字符串以及數值這種基本類型是依據它們的值進行比較的;但像數組、日期以及簡單對象這類object是根據它們的引用進行判斷的。依據引用的判斷會檢查所給的object是否指向內存中的相同地址。下面這個例子會闡述JavaScript中相等運算符的實現原理:
var jangoFett = { occupation: "Bounty Hunter", genetics: "superb" }; var bobaFett = { occupation: "Bounty Hunter", genetics: "superb" }; var callMeJango = jangoFett; // Outputs: false console.log(bobaFett === jangoFett); // Outputs: true console.log(callMeJango === jangoFett);
一方面講,jangoFett和bobaFett這兩個變量引用自兩個擁有完全相同屬性的object,但確實為兩個不同的實例;另一方面,jangoFett和callMeJango指向相同的實例。
因此,當你想要驗證對象相等時,你需要清楚你是想要怎么的相等。如果你是想驗證兩個實例是否完完全全相同,你可以使用JavaScript內置的相等運算符;抑或你是想驗證兩個實例擁有“相同的值”,這樣的話,你可能需要多做些工作。
以下是檢驗object“值相等”的一種基本實現:
function isEquivalent(a, b) { // Create arrays of property names var aProps = Object.getOwnPropertyNames(a); var bProps = Object.getOwnPropertyNames(b); // If number of properties is different, // objects are not equivalent if (aProps.length != bProps.length) { return false; } for (var i = 0; i < aProps.length; i++) { var propName = aProps[i]; // If values of same property are not equal, // objects are not equivalent if (a[propName] !== b[propName]) { return false; } } // If we made it this far, objects // are considered equivalent return true; } // Outputs: true console.log(isEquivalent(bobaFett, jangoFett));
如你所見,想要驗證object實例“值相等”,我們必須去遍歷object中每個屬性,看其是否相等。如果我們把上面實現的這個簡單方案應用在我們的例子中,很多情況都是還沒有處理的。例如:
如果某個屬性是一個object
如果某個屬性值時NaN(JavaScript中唯一一個自身不相等自身的值)
如果a有個屬性的值為undefined,而b中沒有這個屬性(因此都等同于undefined)
想要一個檢驗object實例“值相等”的健壯的方法,最好是使用一個涵蓋各種邊界情況的、經過全面測試的庫。Underscore和Lo-Dash這兩個庫中的_.isEqual方法對處理object深度比較進行了很好的實現。你可以這樣使用它們:
// Outputs: true console.log(_.isEqual(bobaFett, jangoFett));
希望這個JavaScript的小知識點能夠幫助你更好地理解object實例相等的實現原理。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/102324.html
摘要:如果沒有傳入的話如果是類型,則取否則,取這個方法大致和一樣,除了以下返回返回參考知乎中和區別是什么全面解析中的數據類型與類型轉換規范 有哪些判斷相等性的方法 JavaScript現在提供了三種方法來判斷相等性: ===,三個等號即嚴格相等 ==,兩個等號即寬松相等 Object.is(),ES6中用來判斷相等的方法 判斷相等性的細節 ===(嚴格相等) 被比較的兩個數不會進行類型轉...
摘要:還規定了無窮及其它的相應規范,有興趣可自行查找相關資料。其它相同數值相等。類型中,引用同一對象,相等。不同點對的判斷上各有不同。以為代表的相等和相等以為代表的不相等和相等以為代表的相等和不相等相同類型采用嚴格比較。 相等不相等? 先來隨便舉幾個?吧~ 0 == true //? [1] == [1] //? [1] == 1 ...
摘要:在比較字符串數值和布爾值的相等性時,問題還比較簡單。后來,有人提出了這種轉換到底是否合理的質疑。相等時的隱式轉換對于操作符,通常都會先隱式轉換強制轉換,然后再比較它們的相等性。要比較相等性之前,不能將和轉換成其他任何值。 確定兩個變量是否相等是編程中的一個非常重要的操作。 在比較字符串、數值和布爾值的相等性時,問題還比較簡單。但在涉及到對象的比較時,問題就變得復雜了。最早的 ECMAS...
摘要:通常在轉換不同數據類型時,相等和不相等會遵循以下規則若有一個操作數是布爾值,則比較前會將布爾值轉換為數值轉為,轉為。 本文是 重溫基礎 系列文章的第十八篇。今日感受:優化自己的代碼,也是很愉快的事情。 系列目錄: 【復習資料】ES6/ES7/ES8/ES9資料整理(個人整理) 【重溫基礎】1-14篇 【重溫基礎】15.JS對象介紹 【重溫基礎】16.JSON對象介紹 【重溫基礎...
摘要:其他判斷構造函數實例我們看個例子雖然和都是,但是和屬于不同構造函數的實例,為了做出區分,我們認為是不同的對象。 JavaScript 專題系列第十二篇,講解如何判斷兩個參數是否相等 前言 雖然標題寫的是如何判斷兩個對象相等,但本篇我們不僅僅判斷兩個對象相等,實際上,我們要做到的是如何判斷兩個參數相等,而這必然會涉及到多種類型的判斷。 相等 什么是相等?在《JavaScript專題之去重...
閱讀 3228·2021-11-15 11:37
閱讀 2449·2021-09-29 09:48
閱讀 3813·2021-09-22 15:55
閱讀 3014·2021-09-22 10:02
閱讀 2636·2021-08-25 09:40
閱讀 3225·2021-08-03 14:03
閱讀 1691·2019-08-29 13:11
閱讀 1570·2019-08-29 12:49