JavaScript 學習筆記 之 強制類型轉換 (三)

寬鬆相等(==)和嚴格相等(===)

爲什麼這個問題的討論要放在類型轉換這裏呢?

首先,這裏有一個常見的誤區,==是檢查值是否相等,===是檢查值和類型是否相等

然而JavaScript中實際上是

==允許在比較中進行強制類型轉換,而===不允許

首先在性能上,兩者差別不大(大概百萬分之一秒)

我們考慮的只有需不需要強制類型轉換這一點而已

 

抽象相等(==)

ES5中"抽象相等比較法"定義了==運算符的行爲

其中規定如果兩個值類型相同,就僅僅比較它們是否相等

如果兩個值類型不同,==會發生隱式強制類型轉換,會將其中之一或者兩者都轉換爲相同的類型後再比較

但是有幾個特殊情況需要注意

  • NaN不等於NaN
  • +0等於-0

然後還定義了對象的寬鬆相等==,兩個對象指向同一個值的時候即視爲相等(比較對象的時候==和===是完全一樣的,都不會發生強制類型轉換)

常見情況

  1. 字符串和數字之間的比較
  2. 其他類型和布爾類型之間的比較
  3. null和undefined之間的比較
  4. 對象和非對象之間的相等比較

1. 字符串和數字之間的比較

如果==運算符中有一邊是字符串,另一邊是數字

則將字符串強制轉換爲數字後進行比較

如 "42"==42 實際上是 42==42

2. 其他類型和布爾值之間的相等比較

如果==運算符中有一邊是布爾值

則將布爾值強制轉換爲數字後進行比較

			"42" == true //false

3. null和undefined之間的比較

如果==運算符中有一邊是null,另一邊是undefined

則結果爲true

也就是說==中null和undefined相等(他們自身也相等)

除此之外其他值都不存在這種情況

4. 對象和非對象之間的相等比較

如果==運算符中有一方是字符串或數字(布爾值會首先被轉換爲數字)

另一方是對象(對象/函數/數組)

那麼對象首先會進行一個ToPrimitive抽象操作轉換爲對應的基本類型值

ToPrimitive抽象操作通過內部操作[[DefaultValue]]檢查是否有valueOf()方法,如果有並返回基本類型值,就使用該值進行強制類型轉換,如果沒有就使用toString()的返回值(如果存在)來進行強制類型轉換,普通對象的toString()會返回內部[[class]]的值,比如"[object Object]",而數組會將所有單元字符串化後用","連接起來,基本類型的封裝對象則會由valueOf返回基本類型值

一些例外的情況

			Object(null) == null, //false
			Object(undefined) == undefined, //false
			Object(NaN) == NaN, //false

null和undefined沒有封裝對象,因此Object(null)返回的是Object()本身

Object(NaN)等同於new Number(NaN),但是拆封後 NaN == NaN 返回一個false值

抽象關係比較

前面說了==時候的比較規則

這裏說下a<b中涉及的隱式強制類型轉換

(該算法僅針對於a<b,a>b會被處理成b<a)

首先,比較雙方先調用ToPrivate,如果結果出現非字符串,就再調用ToNumber將雙方強制類型轉換爲數字來比較

如果雙方都是字符串,則按照字母順序來比較

但是有一點格外需要注意

JavaScript中的a<=b實際上等同於 !(a>b) 然後會被處理成!(b<a)

		var a = {
			num: 1
		}
		var b = {
			num: 2
		}

		a > b //false
		a == b //false
		a < b //false

		a <= b //true
		a >= b //true

這個例子中a,b都被轉爲"[object Object]",因此 a<b a>b都返回false,而a<=b和a>=b都返回的是!false也就是true

但是==的時候由於兩邊都是對象並且並不指向同一個對象,因此返回false

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章