javascript
JS中捉摸不透的==(宽松等于)
首先來看一個有意思的面試題:
if(a == 3 && a == 4){//... }第一眼看到這個面試題我是拒絕的,這個等式根本不會成立,怎么會存在一個值既等于3并且還同時等于4呢?根本不可能。
但是在神奇的javascript中這個a是存在的。(對javascript要永遠懷著一顆敬畏的心)
var i = 3; var a = new Object();a.valueOf = function(){return i++; }if(a == 3 && a == 4){console.log('等式成立了'); // 打印了 }簡單一看這個面試題有點故弄玄虛,誰會這樣寫代碼?(我之前的想法)
但是這其中的知識點很有用,并且不是很好掌握。
其中的主要知識點就是寬松等于(==)涉及到的隱式類型轉換。在日常開發中總會被提醒盡量不要使用寬松等于,在相等比較時盡可能的使用嚴格等于。但是為什么呢?其實通過上面的面試題就可以看出來,寬松等于太神奇了(晦澀難懂,莫名其妙,坑太多),當然這是對于不太了解寬松等于和類型轉換的我來說的。接下來則會不自量力的盡力來解釋一下類型轉換和寬松等于。
首先對于 == 和 === 的區別常被解釋為 == 并不檢查數據類型,=== 檢查數據類型。但是這個說法并不完全正確。相對正確的說法是 == 允許數據進行類型轉換而 === 并不允許。第一種說法貌似是 === 做了更多的事情,但事實卻不是這樣的。
== 的幾種情況分別是
兩個值類型相同則比較值
1.1 NaN不等于自身
1.2 +0 等于 -0
1.3 兩個對象指向同一個值則相等(不發生強制類型轉換)
1.4 === 對于對象的比較同1.3
數字和字符之間的比較
Boolean和其他之間的比較
對象和非對象之間的比較
#數字和字符串之間的比較
一個String類型值和一個Number類型值之間比較則將String類型值按照 轉換為Number表轉為Number類型。
var a = '1'; var b = 1;console.log(a == b); // true 字符‘1’被轉換成了數字1再作比較則相等 console.log(a === b); // false 并沒有對字符'1'數據類型轉換,數據類型不同則不相等Boolean類型值和其他類型值之間的比較
一個Boolean類型值和一個其他類型值之間比較則首先將Boolean類型值轉換為Number類型,true是1而false是0。
var a = true;console.log(a == 1); // true轉換成了數字1再作比較則相等Object和其他類型值之間的比較
一個Object類型值和一個其他類型值之間比較則將Object類型值按照如下步驟轉化:
以上代碼當對象a和數字1作比較調用valueOf方法獲得字符串‘1’,這時變成了字符串’1’和數字1作比較,根據字符串和數字比較的規則,將字符串轉換成數字等到數字1,然后兩個數字1作比較得出相等。
當沒有valueOf方法或者valueOf方法不返回基本類型值的時候則調用toString方法。
var a = {toString: function(){return 1} };console.log(a == 1); // true到這里開篇的那道面試題則不難理解了,寬松等于中對象和其他類型比較時涉及到了隱式強制類型轉換,首先會調用valueOf方法,如果有必要還會調用toString方法來獲取值來進行比較。
Null和Undefined之間的比較
在寬松等于比較中Null類型值只和自身還有Undefined類型值相等。
console.log(null == undefined); // trueconsole.log(null == false); // falseconsole.log(undefined == false); // falseconsole.log(null == ''); // falseconsole.log(undefined == ''); // falseconsole.log(null == 0); // falseconsole.log(null == ''); // false幾個寬松等于的坑
console.log(![] == []); // true // 取反的優先級高于 ==,所以![]轉為false,false轉為0,[]調用valueOf得到[],所以調用toString得到‘’,然后''轉為0,得到相等console.log(false == []); // true //false轉為 0,[]根據上面的步驟轉為0,得到相等"0" == false; // true 注意"0"并不是假值但是這里卻是相等的,因為 false 轉為 0,變成了數字和字符比較,字符串"0"轉為了數字0得到相等寬松等于中值a與Boolean作比較并不是比較值a是否為真或假,而是值a與轉換過后的Boolean值(0或1)作比較。
參考
你不知道的javascript(中卷)
總結
以上是生活随笔為你收集整理的JS中捉摸不透的==(宽松等于)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JS中的数据类型转换
- 下一篇: 浏览器的同源策略与跨域