今天面試回來,像往常一樣開啟手機,看到QQ群上有個加群申請,進群得回答問題:true == '0'
,看到有個申請的答案為false,然後我就自信的點了拒絕。閒著無聊,開啟電腦在控制檯上輸入題目,結果為false,我就很好奇為什麼是這樣呢?明明兩邊的值都會為true啊,為什麼會錯呢(被拒絕的童鞋不要怪我)。帶這個這個疑問我翻了下你不知道的javascript
javascript中的值分為兩類:
- 可以被強制轉化為false的值
- 其他(可以被強制轉化為true的值)
我們知道能轉換為false的基本型別有,我們稱其為假值:
- undefined
- null
- ""
- 0和NaN
- false
那麼,上面的值既然可以轉化為false,我們的true == '0'
兩邊都可以轉化為true,那麼為什麼不相等呢?
我們先來說下寬鬆相等“==”和“===”。在以往的理解中,我的理解一直是:“==”表示兩個值相等,“===”表死兩個值和型別相等。但是書中說,它們的理解應該說是這樣:“==允許在相等比較中進行強制型別轉化,===不允許”,還是不太理解,兩種理解有什麼區別嗎?暫時放一放,我們往後看。。。
下面摘抄一段樹上寫的區別:
根絕第一種解釋,===似乎比==做的事情更多,因為它還要檢查值的型別,第二種解釋中==的工作量更大一些,因為如果值的型別相同海需要進行強制型別轉化。
如果兩個值的型別不同,我們就需要考慮有沒有強制型別轉化的必要,有就用==,否則用===
接下來我們來看幾種比較來加深理解
- 字串和數字的比較
var a = 4;
var b = "4";
a == b //true
a === b //false
複製程式碼
這個結果大家應該都知道,但是 == 比較時,是將兩邊的值全部轉化為數字呢還是轉化為字串比較呢?未完待續。。。(皮一下:smile:)
哈哈,開個玩笑,公佈答案:轉化為數字。依據就是:
ES5規範11.9.3.4-5這樣定義(ToNumber強制轉化為數字)
(1)如果Type(x)是數字,Type(y)是字串,則返回x == ToNumber(y)的結果
(2)如果Type(x)是字串,Type(y)是數字,則返回ToNumber == y的結果
- 其他型別與布林值比較
我覺得這一塊我們理解的誤區比較多,也是出錯最多的一塊。
例如:
var a = true;
var b = 4;
a == b //false
複製程式碼
以往我們的理解是:數字4是一個真值(與假值對應),會轉化為true,從而兩邊相等。哪裡錯了呢?我們直接來看ES標準
ES5規範11.9.3.6-7這樣定義(ToNumber強制轉化為數字)
(1)如果Type(x)是布林值,則返回ToNumber(x) == y的結果
(2)如果Type(y)是布林值,則返回x == ToNumber(y)的結果
原來比較的時候是將布林值轉化為數字,即:
var a = true;
var b = 4;
var c = true;
var d = "12";
a == b ===> 1 == 4 //false
c == d ===> 1 == "12" ===> 1 == 12 //false
複製程式碼
這樣是不是清楚多了,所以我們判斷的時候別用( a == true)這種判斷。注意:如果x,y中存在 null或undefiend,則參考第三點
- null和undefined之間的比較
ES5規範11.9.3.2-3這樣定義
(1)如果x為null,y為undefined,則返回true
(2)如果x為undefined,y為null,則返回true
在 == 中,null和undefined相等,除此之外不存在這種情況
var a = null;
var b;
a == b //true
a == false //false
b == false //false
a == 0 //false
b == 0 //false
a == "" //false
b == "" //false
複製程式碼
今天就寫到這裡,第一次寫文章,如有什麼不對的地方,還望大家指正