javascript ==與!=的比較規則(加踩坑)
概述: 使用
==
進行比較,當兩個比較元型別不同時,會事先進行型別轉換。(這也是其與===
的本質區別)
轉換規則:
- 當只有一方是
boolean
時,先將boolean
轉number
。(true: 1
,false: 0
)- 當一方
number
一方string
時,string
轉number
。(Number(string)
, 結果可能是NaN
)- 當只有一方是
object
時,object
呼叫valueOf()
獲取其原始值
(1)若valueOf()
方法返回值的型別不是物件(null
除外),則使用該返回值繼續進行 1. 2. 的判斷
(2)否則,object
呼叫toString()
獲取其返回值
(2-1)若toString()
方法返回值的型別不是物件,則使用該返回值繼續進行 1. 2. 的判斷
(2-2)否則,直接返回 false
這一部分看不懂的話,可以看看後邊的第一點的示例比較規則:
undefined == null
為 true- 在與
undefined
和null
比較前,另外一個元不會進行型別轉換- 兩個
object
比較時,只有兩個物件相同(也就是其值是同一個指標或者說對同一個物件的引用),==
才會返回 true。例如:{} == {}
返回 false。NaN
不與任何值相等,包括它自己(NaN == NaN
返回 false)
一、轉換規則3的舉例說明
let o = {};
// eg1:
o.valueOf = () => 1;
o.toString = () => 2;
o == 1; // true
o == 2; // false
// eg2:
o.valueOf = () => { return []; }
o.toString = () => 2;
o == 2; // true
o == []; // false,這時使用的是比較規則3,兩個物件比較,判斷指標是否相同
// eg3:
o.valueOf = () => { return null; } // return undefined 也是同樣道理
o.toString = () => 2;
o == 2; // false valueOf的返回值是null,不是普通物件,直接使用null了。null與2比較返回false
o == null; // false 此時使用的是比較規則2,object不進行型別轉換
// eg4:
o.valueOf = () => { return []; }
o.toString = () => { return o; }
o == 任何非o的原始型別資料或物件 // false
o == o; // true 此時使用的是比較規則3,物件比較判斷是否是同一物件(指標)
二、分析 [] == []
返回 false,[] == ![]
返回 true
-
[] == []
返回 falselet l1 = []; let l2 = []; // 因為 l1, l2 實際上是兩個不同的物件(指標),根據比較規則 3 ,返回 false
-
[] == ![]
返回 truelet l1 = []; let l2 = []; /* 比較步驟 1. l1 == !l2 ? !l2 => ![] => false (! 優先順序比 == 高) 2. l1 == false ? false => 0 (轉換規則1,一方boolean,boolean轉number) 3. l1 == 0 ? l1 => l1.valueOf() => [] => (非null物件,不行) => l1.toString() => "" (轉換規則3,一方為物件時...) 4. "" == 0 ? "" => 0 (轉換規則2,一方number一方string,string轉number) 5. 0 == 0 ,返回true */
二、分析 {} == {}
、 {} == !{}
均返回 false
-
{} == {}
返回 falselet o1 = {}; let o2 = {}; // 因為 o1, o2 實際上是兩個不同的物件(指標),根據比較規則 3 ,返回 false
-
{} == !{}
返回 falselet o1 = {}; let o2 = {}; /* 比較步驟 1. o1 == !o2 ? !o2 => !{} => false (! 優先順序比 == 高) 2. o1 == false ? false => 0 (轉換規則1,一方boolean,boolean轉number) 3. o1 == 0 ? o1 => o1.valueOf() => {} => ({}是物件,不行) => o1.toString() => '[object object]' (轉換規則3,一方為物件時...) 4. '[object object]' == 0 ? '[object object]' => NaN (轉換規則2,一方number一方string,string轉number) 5. NaN == 0 返回 false (比較規則4,NaN不與任何值相等) */
相關文章
- 規則引擎與ML模型的比較 - xLaszlo模型
- 規則引擎與機器學習比較與結合機器學習
- 字符集和比較規則
- JavaScript與WebAssembly進行比較JavaScriptWeb
- 從根上理解 MySQL 的字符集和比較規則MySql
- JavaScript正則爬坑JavaScript
- 前端工程不瞭解?帶你踩坑加爬坑。前端
- js比較日期 - JavaScriptJSJavaScript
- Webpack的踩坑與彙總Web
- JavaScript 比較相同的字元返回falseJavaScript字元False
- JavaScript中this的繫結規則JavaScript
- 微信小程式框架wepy踩坑記錄(與vue對比)微信小程式框架Vue
- JavaScript this 繫結規則JavaScript
- volatile與Atomic的比較
- 微信支付 V3 RSA 加簽踩坑
- JavaScript 倒數計時踩坑集錦JavaScript
- ==與equals比較
- javascript訪問不同物件的速度比較JavaScript物件
- 四種在Javascript比較物件的方法JavaScript物件
- JavaScript - 函式 setTimeout 和 setInterval 的比較JavaScript函式
- Oracle vs PostgreSQL,研發注意事項(8)- Oracle資料比較規則OracleSQL
- JavaScript比較兩個時間JavaScript
- 使用phoenix踩的坑與設計思考
- ESLint規則中的JavaScript知識EsLintJavaScript
- MyBatis Generator嘗試與踩坑MyBatis
- pwa+webpack,初探與踩坑Web
- JavaScript 匿名函式與具名函式執行效率比較JavaScript函式
- XTask與RxJava的使用比較RxJava
- Flutter與React Native的比較FlutterReact Native
- PostgreSQL與MySQL的比較 - hackrMySql
- MVVM與MVC模式的比較MVVMMVC模式
- golang的踩坑Golang
- 連結器規則會引入的巨坑
- Python、JavaScript和Rust的Web效能比較 - AlexPythonJavaScriptRustWeb
- jQuery - jQuery $(document).ready() 和 JavaScript [removed]() 的比較jQueryJavaScriptREM
- Go 與 C++ 的對比和比較GoC++
- Vuex與Redux比較VueRedux
- Hibernate與mybatis比較MyBatis