你真的理解==和===嗎
開門見題
說出以下幾個表示式的結果
var obj1 = { name: '張三'}
var obj2 = obj1
var obj3 = { name: '張三'}
null == undefined
123 == '123'
false == 0
NaN == false
obj1 == obj2
obj1 == obj3
補充知識 要想回答上述問題,必須理解js在執行==
時候的一些資料轉換規則和成文的規定。ECMA-262對==
的約定如下:
x==y
- 如果x和y的型別相同,
- 如果x是undefined,return true
- 如果x是null,return true
- 如果x是Number
- x是NaN,return false
- y是NaN,return false
- x,y數值相同,return true
- x是+0,y是-0,return true
- x是-0,y是+0,return true
- 如果x是String,y必須和x長度內容都相同才return true,否則return false
- 如果x是Boolean,x,y相同return true,否則return false
- 如果x,y引用同一個物件,return true,否則return false
- x是null,y是undefined,return true
- x是undefined,y是null,return true
- x是Number,y是String,return x == ToNumber(y)
- x是String,y是Number,return ToNumber(x) == y
- x是Boolean,return ToNumber(x) == y
- y是Boolean,return x == ToNumber(y)
- x是String或Number,y是Object,return x == ToPrimitive(y)
- x是Object,y是String或Number,return ToPrimitive(x) == y
- return false
你可能注意到了這樣兩個函式
ToNumber()
引數型別 | 結果 |
---|---|
Undefined | NaN |
Null | +0 |
Boolean | true為1,false為+0 |
Number | 引數本身 |
String | 簡單理解,能轉換成數字的就會轉換成數字,比如數字字串,十六進位制的數字等,轉換失敗則返回NaN(詳見ECMA-262-9.3.1,內容較多,不展開敘述) |
Object | 兩步轉換操作:1. ToPrimitive(input argument, hint Number) 2. ToNumber() |
ToPrimitive()
引數型別 | 結果 |
---|---|
Undefined | 輸入值 |
Null | 輸入值 |
Boolean | 輸入值 |
Number | 輸入值 |
String | 輸入值 |
Object | 呼叫DefaultValue方法 |
好吧,又多了一個DefaultValue方法
ToPrimitive()
細心的你發現上面ToNumber對於Object的轉換裡有這麼一句ToPrimitive(input argument, hint Number)
,就是說呼叫ToPrimitive的時候,除了傳入要轉化的值,還傳了一個hint引數,這個引數可以為Number,也可以為String。那麼什麼時候傳入這兩個引數,同時又有啥區別?
-
如果引數是
hint Number
:- 先執行
valueOf
,如果返回值是原始值,則返回原始值 - 否則執行
toString
,如果返回值是原始值,則返回原始值 - 報錯
- 先執行
- 如果引數是
hint String
:- 先執行
toString
,如果返回值是原始值,則返回原始值 - 否則執行
valueOf
,如果返回值是原始值,則返回原始值 - 報錯
- 先執行
如果input argument是內建的Date型別,則引數是hint String
,否則預設hint Number
。
說了這麼多,我們回到上面的題目,一一解答:
-
null == undefined
。根據上面第二條,寫的明明白白,結果是true。 -
123 == '123'
。根據上面第四條return 123 == ToNumber('123')
,而ToNumber('123')
的結果為123,所以return 123 == 123
,根據1-3-3,返回true。 -
false == 0
。根據上面第六條,return ToNumber(false) == 0
,而ToNumber(false)
的值為+0,所以+0 == 0
,根據1-3-3,返回true。 -
NaN == false
。看到很多別的同學說這裡是做了各種型別轉換,其實我認為這裡是由於沒有匹配到任何規則,所以根據第十條返回false,也就是說並沒有做什麼型別轉換。 -
obj1 == obj2
。根據1-6,由於obj1和obj2指向同一個引用,所以返回true。 -
obj1 == obj3
。根據1-6,由於obj1和obj2指向不同引用,所以返回false。
把上面題目中的==
換成===
,試問結果會發生怎樣的變化?這裡我就不說了,推理方式同上,根據如下規則,答案請各位看官自行補充。
x===y
- 如果x,y型別不同,return false
- 如果x是undefined,return true
- 如果x是null,return true
- 如果x是Number
- 如果x是NaN,return false
- 如果y是NaN,return false
- x,y數值相同,return true
- x是+0,y是-0,return true
- x是-0,y是+0,return true
- return false
- 如果x是String,y必須和x長度內容都相同才return true,否則return false
- 如果x,y引用同一個物件,return true,否則return false
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2508/viewspace-2805307/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 你真的理解this嗎
- 你真的理解setState嗎?
- 你真的理解 getLocationInWindow 了嗎?
- [譯]你真的理解grok嗎
- 你真的理解 new 了嗎?
- 你真的理解 flex 佈局嗎?Flex
- 三層,你真的理解了嗎?
- C++中的i++和++i你真的理解嗎?C++
- MVP模式(2):你真的理解下抽象類和介面嗎??MVP模式抽象
- 你真的理解什麼是死鎖嗎?
- 你真的理解JS的繼承了嗎?JS繼承
- 你真的理解@import和link引入樣式的區別嗎Import
- 高併發,你真的理解透徹了嗎?
- 你真的理解反向傳播嗎?面試必備反向傳播面試
- 你真的理解T-sql中的NULL嗎?SQLNull
- 你真的瞭解 Cookie 和 Session 嗎?CookieSession
- 你真的瞭解 Cookie 和 Session 嗎CookieSession
- 你真的瞭解 Session 和 Cookie 嗎?SessionCookie
- 你真的理解函數語言程式設計嗎?函數程式設計
- 你真的理解【函數語言程式設計】嗎?函數程式設計
- 你真的理解 Webpack?Web
- 你真的理解 Spring Boot 專案中的 parent 嗎?Spring Boot
- 你真的理解Python中的賦值、傳參嗎?Python賦值
- Android效能優化(七)之你真的理解ANR嗎?Android優化
- 你真的知道 == 和 equals 的區別嗎?
- 你真的懂 == 和 equals 的區別嗎?
- WebView你真的熟悉嗎?WebView
- 你真的知道JS嗎JS
- 你真的理解機器學習中偏差 - 方差之間的權衡嗎?機器學習
- 分散式和事務你真的很熟嗎?分散式
- 你真的很熟分散式和事務嗎?分散式
- ViewStub你真的瞭解嗎View
- 你真的知道跨域嗎跨域
- 你真的瞭解mongoose嗎?Go
- TCP|你真的懂 HTTP 嗎?TCPHTTP
- 你真的懂函式嗎?函式
- 你真的會用 Babel 嗎?Babel
- 你真的瞭解 WebSocket 嗎?Web