摘要:還規定了無窮及其它的相應規范,有興趣可自行查找相關資料。其它相同數值相等。類型中,引用同一對象,相等。不同點對的判斷上各有不同。以為代表的相等和相等以為代表的不相等和相等以為代表的相等和不相等相同類型采用嚴格比較。
相等不相等?
先來隨便舉幾個?吧~
"0" == true //? [1] == [1] //? [1] == 1 //? null == false //? null == undefined //? NaN === NaN //? +0 === -0 //? Object.is([], []) //? Object.is(-0, +0) //? Object.is(NaN, NaN) //? var arr = [NaN, 0, +0] arr.indexOf(-0) //? arr.indexOf(NaN) //? arr.includes(-0) //? arr.includes(NaN) //?
可能 ±0、NaN 會糾結一點,還是比較基礎的,也許很多人一眼掃過去便知道答案了,網上也已經有了很多相關的經驗總結。我在這里結合官方規范進行了整理,希望能帶給你不一樣的認識。
預備知識 ECMAScript Language Types傳送門。根據最新規范,EcmaScript 一共有7種語言類型:
Undefined
Null
Number
String
Boolean
Symbol
Object
我們經常把 Object 類型稱為 引用數據類型,其它5種則為基本數據類型。(Symbol怎么說..?
ToNumber傳送門。任意 EcmaScript 類型轉化為 Number 類型:
類型 | 結果 | |
---|---|---|
Undefined | NaN | |
Null | +0 | |
Boolean | true -> 1,false -> +0 | |
Number | 不轉變 | |
String | 空字符串 -> +0,有效的數字 -> 十進制數字,其它 -> NaN | |
Object | 先ToPrimitive(hint Number),再ToNumber | |
Symbol | 拋錯,TypeError 錯誤 |
傳送門。內部方法,主要功能是將引用數據類型轉化為基本數據類型。
根據內部標記 hint 的不同有不同的調用順序。
hint有三種:default、number、string。default 默認遵照 number 規則。
default/number:先 valueOf,后 toString。一般轉化規則皆如此。
string:先 toString,后 valueOf。如Date對象方法、String()轉化等。
如果 toString/valueOf 中某一方法返回類型不為對象類型,則直接返回該值,不會繼續調用后面方法。如果兩者都返回對象類型,會拋 TypeError 錯誤。
-0、+0、0 的疑惑明明日常沒什么卵用,為什么會有±0?
其實遵從IEEE754標準的編程語言都有±0的概念,IEEE754標準的64位浮點數,是以1+11+53形式的符號位+階數位+尾數位表示。
符號位、階數位、尾數位都是0,那便是+0,也就是常規的數字0。
符號位為1,階數位、尾數位都是0,那便是 -0。
IEEE754還規定了NaN、無窮及其它的相應規范,有興趣可自行查找相關資料。
PS這部分其實是后加的,你會發現每個知識點都是緊密相連的,構成了一個龐大的知識網絡,限于篇幅我不會詳細介紹,但我會盡量貼出規范出處,大家可自行研究。
SameValueNonNumber 內部方法SameValueNonNumber 方法接收兩個參數 x 和 y ,其中 x 和 y 都不是 Number 類型,該方法返回 true 或 false。
主要規則斷言:x 不是 Number 類型。
斷言:x 和 y 是 相同類型。
如果 x 是 Undefined 類型,返回 true 。
如果 x 是 Null 類型,返回 true 。
如果 x 是 String 類型:
如果 x 和 y 長度相同且相應編碼單元相同,返回 true 。
否則返回 false 。
如果 x 是 Boolean 類型:
如果 x 和 y 都是true 或者 都是false,返回 true 。
否則返回 false 。
如果 x 是 Symbol 類型:
如果 x 和 y 都是相同 Symbol 值,返回 true 。
否則返回 false 。
如果 x 和 y 指向同一對象,返回 true 。否則返回 false 。
小結相同類型比較規則(除Number類型)
都是 undefined,相等。
都是 null,相等。
String 類型中,都是相同字符串,相等。
Boolean 類型中,都是 true 或者 都是 false,相等。
Symbol 類型中,都是相同 Symbol 值,相等。
Object 類型中,引用同一對象,相等。
使用哪些 JavaScript 公開方法采用了 SameValueNonNumber 比較呢?
公開方法木有
接著看下去你就會知道,撇開數值類型比較,SameValueNonNumber 是 SameValue、SameValueZero、 === 的公共方法。
SameValueZero 內部方法SameValueZero 方法接收兩個參數 x 和 y ,其中 x 和 y 是 EcmaScript 任意類型值,該方法返回 true 或 false。
主要規則如果 x 和 y 的類型不同,返回 false 。
如果 x 是 Number 類型:
如果 x 和 y 都是 NaN ,返回 true 。
如果 x 是 -0 ,y 是 +0 ,返回 true 。
如果 x 是 +0 ,y 是 -0 ,返回 true 。
如果 x 和 y 數值相等,返回 true 。
返回 false 。
返回 SameValueNonNumber(x, y) 方法的返回值。
小結不同類型不相等。
Number 類型中:±0 相等。NaN 和 NaN 相等。其它相同數值相等。
SameValueNonNumber 比較:
都是 undefined,相等。
都是 null,相等。
String 類型中,都是相同字符串,相等。
Boolean 類型中,都是 true 或者 都是 false,相等。
Symbol 類型中,都是相同 Symbol 值,相等。
Object 類型中,引用同一對象,相等。
使用哪些 JavaScript 公開方法采用了 SameValueZero 比較呢?
Array.prototype.includes
Map.prototype.delete
Map.prototype.has
Map.prototype.set
Set.prototype.delete
Set.prototype.has
Set.prototype.add
ArrayBuffer 和 DataView 部分方法
SameValue 內部方法SameValue 方法接收兩個參數 x 和 y ,其中 x 和 y 是 EcmaScript 中任意類型值,該方法返回 true 或 false。
主要規則如果 x 和 y 的類型不同,返回 false 。
如果 x 是 Number 類型:
如果 x 和 y 都是 NaN ,返回 true 。
如果 x 是 -0 ,y 是 +0 ,返回 false 。
如果 x 是 +0 ,y 是 -0 ,返回 false 。
如果 x 和 y 數值相等,返回 true 。
返回 false 。
返回 SameValueNonNumber(x, y) 方法的返回值。
小結不同類型不相等。
Number 類型中:±0 不相等。NaN 和 NaN 相等。其它相同數值相等。
SameValueNonNumber 比較:
都是 undefined,相等。
都是 null,相等。
String 類型中,都是相同字符串,相等。
Boolean 類型中,都是 true 或者 都是 false,相等。
Symbol 類型中,都是相同 Symbol 值,相等。
Object 類型中,引用同一對象,相等。
使用哪些 JavaScript 公開方法采用了 SameValue 比較呢?
Object.is
在最新的 ES 規范 中,你會發現許多其它內部方法和公開方法都應用了 SameValue 比較方法,其中大部分也沒有涉及數值比較。
至于為什么是 SameValue 方法,而不是 SameValueZero或===。其實我也不知道。。。我個人傾向于認為:SameValue 方法原本在 ES5 規范中便存在了,最新的規范是為了保持規范一致而繼續沿用。
=== 嚴格相等運算Strict Equality Comparison,x === y,返回 true 或者 false。
主要規則如果 x 和 y 的類型不同,返回 false 。
如果 x 是 Number 類型:
如果 x 是 NaN ,返回 false 。
如果 y 是 NaN ,返回 false 。
如果 x 和 y 數值相等,返回 true 。
如果 x 是 -0 ,y 是 +0 ,返回 true 。
如果 x 是 +0 ,y 是 -0 ,返回 true 。
返回 false 。
返回 SameValueNonNumber(x, y) 方法的返回值。
小結不同類型不相等。
Number 類型中:±0 相等。NaN 和 NaN 不相等。其它相同數值相等。
SameValueNonNumber比較:
都是 undefined,相等。
都是 null,相等。
String 類型中,都是相同字符串,相等。
Boolean 類型中,都是 true 或者 都是 false,相等。
Symbol 類型中,都是相同 Symbol 值,相等。
Object 類型中,引用同一對象,相等。
使用哪些 JavaScript 公開方法采用了 === 比較呢?
=== 嚴格相等運算
左右兩邊是相同類型的 == 相等運算
switch語句中的case
Array.prototype.indexOf
Array.prototype.lastIndexOf
== 相等運算Abstract Equality Comparison,x == y,返回 true 或者 false。
主要規則
如果 x 和 y 的類型相同:
返回嚴格相等運算結果 x === y 。
如果 x 是 null ,y 是 undefined ,返回 true 。
如果 x 是 undefined ,y 是 null ,返回 true 。
如果 x 是 Number 類型 ,y 是 String 類型,返回 x == ToNumber(y) 運算結果。
如果 x 是 String 類型 ,y 是 Number 類型,返回 ToNumber(x) == y 運算結果。
如果 x 是 Boolean 類型 ,返回 ToNumber(x) == y 運算結果。
如果 y 是 Boolean 類型 ,返回 x == ToNumber(y) 運算結果。
如果 x 是 Number、String、Symbol 中任意一個類型 ,y 是 Object 類型,返回 x == ToPrimitive(y) 運算結果。
如果 y 是 Number、String、Symbol 中任意一個類型 ,x 是 Object 類型,返回 ToPrimitive(x) == y 運算結果。
返回 false 。
小結相同類型:遵循 === 嚴格相等比較規則。
null == undefined,相等。
不同類型:
基本數據類型轉換為 Number 類型再 == 比較。
引用數據類型執行內部 ToPrimitive方法后再 == 比較。
使用哪些 JavaScript 公開方法采用了 == 比較呢?
只有這只 == 相等運算
相等不相等開頭的答案。如果對結果感到好奇,不妨對著上面的過程比對~
"0" == true // false [1] == [1] // false [1] == 1 // true null == false // false null == undefined // true NaN === NaN // false +0 === -0 // true Object.is([], []) // false Object.is(-0, +0) // false。見SameValue Object.is(NaN, NaN) // true。見SameValue var arr = [NaN, 0, +0] arr.indexOf(-0) // 1。見=== arr.indexOf(NaN) // -1。見=== arr.includes(-0) // true。見SameValueZero arr.includes(NaN) // true。見SameValueZero總結
SameValueZero、SameValue、===這仨完全差不多嘛!
相同點:
- 不同類型即不相等。 - 相同類型遵從`SameValueNonNumber`規則。
不同點:對±0、NaN 的判斷上各有不同。
以 Array.prototype.includes 為代表的SameValueZero
±0 相等
NaN 和 NaN 相等
以 Object.is 為代表的SameValue
±0 不相等
NaN 和 NaN 相等
以 ===、Array.prototype.indexOf 為代表的===
±0 相等
NaN 和 NaN 不相等
==
相同類型采用===嚴格比較。
不同類型會隱式轉換:
基本數據類型轉換為 Number 類型再 == 比較。
引用數據類型執行 ToPrimitive 轉換后再 == 比較。
undefined/null 特例。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92237.html
摘要:前端渲染過程的二三事本文不會介紹整個前端渲染過程的步驟,只是記錄最近閱讀的文章的些許思考和感悟。那么現在我們可以明白這個問題的關鍵所在了,因為在大部分頁面中是擁有的,而由于其解析順序,那么在事件之前必定已經成功構造樹。 前端渲染過程的二三事 本文不會介紹整個前端渲染過程的步驟,只是記錄最近閱讀的文章的些許思考和感悟。(文章地址一(系列),文章地址二) 希望大家在閱讀這篇文章之前能將上述...
摘要:但對于整個事件流上的別的元素來說,執行順序還會受到另外一個因素的影響。以上面的場景為例,在捕獲階段執行的事件,如果執行,則事件流終止,不會到達目標階段,的世界則不會被執行執行結果為線上參考事件流 向dom綁定事件的事件的三種方式 行內綁定 按鈕 js內綁定 btnDom.onclick = function clickHandler() { console.log(click)...
摘要:分表字段的選擇。問題產生之前提到在分表應用上線前我們需要將原有表的數據遷移到新表中,這樣才能保證業務不受影響。雖說凌晨的業務量下降,但依然有少部分的請求過來,也會出現各種數據庫異常。 showImg(https://segmentfault.com/img/remote/1460000019462791?w=496&h=285); 前言 本篇是上一篇《一次分表踩坑實踐的探討》,所以還沒...
閱讀 1905·2021-11-25 09:43
閱讀 1405·2021-11-22 14:56
閱讀 3280·2021-11-22 09:34
閱讀 2010·2021-11-15 11:37
閱讀 2256·2021-09-01 10:46
閱讀 1396·2019-08-30 15:44
閱讀 2294·2019-08-30 13:15
閱讀 2393·2019-08-29 13:07