以下內(nèi)容均為個人整理的觀點,一個個字碼出來的,不喜勿噴
我們先做一道面試題吧
console.log('[]==![]');
請想出你的答案,并說服你自己吧。
然后你再做一道吧:
console.log('{}==!{}');
哈哈哈哈哈哈哈哈
我們再做一道面試題吧
console.log([1,2,3] == '1,2,3')
自己嘗試一下,做對了嗎?
其實這三道題牽扯到了兩個知識點,一個是類型的轉(zhuǎn)換和比較運算符,今天重點說類型的轉(zhuǎn)換。
答案及解析見文末~~~
-
轉(zhuǎn)換成Number類型的規(guī)則
//如果轉(zhuǎn)換的是數(shù)字,那么結(jié)果不變 console.log(Number(2));//2 //如果轉(zhuǎn)換的是字符串,但是是純數(shù)值,那么結(jié)果是數(shù)字 console.log(Number('-23'));//-23 //如果轉(zhuǎn)換的是字符串,但是是包含非數(shù)字內(nèi)容,那么結(jié)果是NaN console.log(Number('abx11'));//NaN //如果轉(zhuǎn)換的是字符串,但是是包含非數(shù)字內(nèi)容,那么結(jié)果是NaN console.log(Number('11abx'));//NaN //如果轉(zhuǎn)換的是null,結(jié)果是0 console.log(Number(null));//0 //如果轉(zhuǎn)換的是undefined,那么結(jié)果是NaN console.log(Number(undefined));//NaN //如果轉(zhuǎn)換的是布爾值true,那么結(jié)果是1 console.log(Number(true));//1 //如果轉(zhuǎn)換的是布爾值false,那么結(jié)果是0 console.log(Number(false));//0 //如果轉(zhuǎn)換的是空數(shù)組,那么結(jié)果是0 console.log(Number([]));//0 //如果轉(zhuǎn)換的是非空數(shù)組,那么結(jié)果是NaN console.log(Number(["2","3"]));//NaN //如果轉(zhuǎn)換的是對象(無論是否是空的),那么結(jié)果是NaN console.log(Number({}));//NaN
當(dāng)然將其他類型轉(zhuǎn)換成number類型的還有parseInt和parseFloat,但是今天討論的是轉(zhuǎn)化規(guī)則,對其他的不做詳談。
-
轉(zhuǎn)化成String類型的規(guī)則
//如果轉(zhuǎn)換的是數(shù)字,那么結(jié)果是字符串的數(shù)值 console.log(String(3))//'3' //如果轉(zhuǎn)換的是字符串,那么結(jié)果還是原字符串 console.log(String('abc'))//'abc' //如果轉(zhuǎn)換的是null,那么結(jié)果是字符串‘null’ console.log(String(null))//'null' //如果轉(zhuǎn)換的是undefined,那么結(jié)果是字符串'undefined' console.log(String(undefined))//'undefined' //如果轉(zhuǎn)換的是布爾值true,那么結(jié)果是字符串'true' console.log(String(true))//'true' //如果轉(zhuǎn)換的是布爾值false,那么結(jié)果是字符串'false' console.log(String(false))//'false' //如果轉(zhuǎn)換的是空對象,那么結(jié)果是字符串'[object Object]' console.log(String({}))//'[object Object]' //如果轉(zhuǎn)換的是非空對象,那么結(jié)果仍是字符串'[object Object]' console.log(String({name:"lily"}))//'[object Object]' //如果轉(zhuǎn)換的是空數(shù)組,那么結(jié)果是空字符串 console.log(String([]))//空字符串 //如果轉(zhuǎn)換的是非空數(shù)組,那么結(jié)果是字符串'2,3'(數(shù)組的值包含逗號都在字符串中) console.log(String([2,3]))//'2,3'
當(dāng)然還有toString等方法也可以將其他類型轉(zhuǎn)化成字符串,這個文章不做詳細討論
-
轉(zhuǎn)換成Boolean類型的規(guī)則
//如果轉(zhuǎn)換的是數(shù)字0,那么結(jié)果false console.log(Boolean(0))//false //如果轉(zhuǎn)換的是數(shù)字非0,那么結(jié)果true console.log(Boolean(-1))//true //如果轉(zhuǎn)換的是數(shù)字非0,那么結(jié)果true console.log(Boolean(3))//true //如果轉(zhuǎn)換的是空字符串,那么結(jié)果false console.log(Boolean(""))//false //如果轉(zhuǎn)換的是數(shù)字非空字符串,那么結(jié)果true console.log(Boolean("abc"))//true //如果轉(zhuǎn)換的是null,那么結(jié)果false console.log(Boolean(null))//false //如果轉(zhuǎn)換的是undefined,那么結(jié)果false console.log(Boolean(undefined))//false //如果轉(zhuǎn)換的是布爾值true,那么結(jié)果仍然是true console.log(Boolean(true))//true //如果轉(zhuǎn)換的是布爾值false,那么結(jié)果仍然是false console.log(Boolean(false))//false //如果轉(zhuǎn)換的是空對象,那么結(jié)果是true console.log(Boolean({}))//true //如果轉(zhuǎn)換的是非空對象,那么結(jié)果仍然是true console.log(Boolean({name:"lily"}))//true //如果轉(zhuǎn)換的是空數(shù)組,那么結(jié)果仍然是true console.log(Boolean([]))//true //如果轉(zhuǎn)換的是非空數(shù)組,那么結(jié)果仍然是true console.log(Boolean([3,4]))//true
好了,知道上邊的規(guī)則之后,我們來說一下剛才的3道題了
console.log('[]==![]'); console.log('{}==!{}'); console.log([1,2,3] == '1,2,3')
咦,我雖然知道了轉(zhuǎn)換規(guī)則,但是好像缺了點什么?
那就是比較的時候怎么進行的轉(zhuǎn)換的呢? (只討論==的情況)
- 如果有一個操作數(shù)是布爾值,則在比較相等性之前先將其轉(zhuǎn)換為數(shù)值——false轉(zhuǎn)換為0,而true轉(zhuǎn)換為1;
//先將true轉(zhuǎn)化成數(shù)字1,然后比較相等,返回true console.log(true==1)//true
- 如果一個操作數(shù)是字符串,另一個操作數(shù)是數(shù)值,在比較相等性之前先將字符串轉(zhuǎn)換為數(shù)值
//先將‘34’轉(zhuǎn)換成數(shù)字34,然后比較返回true console.log("34"==34)//true
- 如果有一個操作數(shù)是NaN,則相等操作符返回 false ,而不相等操作符返回 true。重要提示:即使兩個操作數(shù)都是NaN,相等操作符也返回 false了;因為按照規(guī)則, NaN 不等于 NaN
//首先將'abc'轉(zhuǎn)換成NaN,NaN和任何相比都是false console.log("abc"==34);//false //NaN和NaN比也是false console.log(NaN==NaN)//false
- 兩個等號判斷等于的時候null 和undefined 是相等的
console.log(null==undefined);//true
- 如果兩個操作數(shù)都是對象,則比較它們是不是同一個對象,如果兩個操作數(shù)都指向同一個對象,則相等操作符返回 true;否則, 返回false
//只是兩個空對象,但是分別是兩個對象,所以不相等 console.log({}=={})//false var obj1 = {}; var obj2 = obj1; //obj1和obj2的地址都指向同一個對象,所以相等 console.log(obj2==obj1)//true
[] 和 {} 都是屬于引用類型,引用類型是存放在棧內(nèi)存中的,而在堆內(nèi)存中會有一個或者多個地址來指向這個棧內(nèi)存相對應(yīng)的數(shù)據(jù)。所以在使用 == 操作符的時候,對于引用類型的數(shù)據(jù),比較的是地址,而不是真實的值(會在引用類型值和基本類型值章節(jié)詳細講解)
終于能說這個面試題解析了
第一題:
[]==![]
- 首先!(非操作符)優(yōu)先級高于==(等于操作符),所以先執(zhí)行
![]
- 而空數(shù)組轉(zhuǎn)化成布爾值是true,所以
![]
就是false
*然后開始比較,剛才說了 如果有一個操作數(shù)是布爾值,則在比較相等性之前先將其轉(zhuǎn)換為數(shù)值,所以==
之前空數(shù)組轉(zhuǎn)化數(shù)字是0,==
之后false轉(zhuǎn)換數(shù)字是0- 所以
[]==![]
為真(true)
第二題:
[]==![],和上一題道理一樣,但是結(jié)果不一樣
- 首先!(非操作符)優(yōu)先級高于==(等于操作符),所以先執(zhí)行
!{}
- 而空對象轉(zhuǎn)化成布爾值是true,所以
![]
就是false
*然后開始比較,==
之前空對象轉(zhuǎn)化數(shù)字是NaN,==
之后false轉(zhuǎn)換數(shù)字是0,而NaN和任何值比較都是false- 所以
{}==!{}
為假(false)
第三題:
[1,2,3] == '1,2,3'
- 首先,一個值是字符串,另一個值是對象,所以將對象轉(zhuǎn)化成字符串
- 而[1,2,3] 轉(zhuǎn)換成字符串就是 '1,2,3'
- 所以
[1,2,3] == '1,2,3'
為真(true)
好了12點多了,今天就嘮嗑到這里了,有疑問和建議可以留言,其他內(nèi)容請期待以后的內(nèi)容~
謝謝觀看~
拜拜,晚安!!!