我們通過(guò)第一節(jié)知道了js的數(shù)據(jù)類(lèi)型有6中,不包含symbol。接下來(lái)我們來(lái)了解了解這些神奇的東西QaQ
顯示轉(zhuǎn)換:人為的去改變數(shù)據(jù)的類(lèi)型,又叫強(qiáng)制轉(zhuǎn)換
隱式轉(zhuǎn)換:在js中,當(dāng)運(yùn)算符在運(yùn)算時(shí),如果兩邊數(shù)據(jù)不統(tǒng)一,編譯器會(huì)自動(dòng)將運(yùn)算符兩邊的數(shù)據(jù)做一個(gè)數(shù)據(jù)類(lèi)型轉(zhuǎn)換,轉(zhuǎn)成一樣的數(shù)據(jù)類(lèi)型再計(jì)算
顯示轉(zhuǎn)換常用的有下列幾種
先了解一下NaN(Not a Number, 非數(shù)字)NaN不能通過(guò)相等操作符(== 和 ===)來(lái)判斷, 因?yàn)?NaN 不與任何值相等, 即使是NaN自己本身,一般出現(xiàn)計(jì)算失敗,解析數(shù)字失敗,與NaN計(jì)算
- Boolean() -- 將一個(gè)值轉(zhuǎn)換為其對(duì)應(yīng)的Boolean值
| 數(shù)據(jù)類(lèi)型 | 轉(zhuǎn)換為true | 轉(zhuǎn)換為false |
|---|---|---|
| Boolean | true | false |
| String | 任何非空字符 | 空字符 |
| Number | 任何非零數(shù)字值 | 0和NaN |
| Object | 任何對(duì)象 | null |
| Undefined | N/A(不適用) | undefined |

- Number 將一個(gè)值轉(zhuǎn)換為其對(duì)應(yīng)的數(shù)值類(lèi)型
(1)如果是布爾值,true和false分別被轉(zhuǎn)換為1和0
(2)如果是數(shù)字值,返回本身。
(3)如果是null,返回0.
(4)如果是undefined,返回NaN。
(5)如果是字符串,遵循以下規(guī)則:
1、如果字符串中只包含數(shù)字,則將其轉(zhuǎn)換為十進(jìn)制(忽略前導(dǎo)0)
2、如果字符串中包含有效的浮點(diǎn)格式,將其轉(zhuǎn)換為浮點(diǎn)數(shù)值(忽略前導(dǎo)0)
3、如果是空字符串,將其轉(zhuǎn)換為0
4、如果字符串中包含非以上格式,則將其轉(zhuǎn)換為NaN
(6)如果是對(duì)象,則調(diào)用對(duì)象的valueOf()方法,然后依據(jù)前面的規(guī)則轉(zhuǎn)換返回的值。如果轉(zhuǎn)換的結(jié)果是NaN,則調(diào)用對(duì)象的toString()方法,再次依照前面的規(guī)則轉(zhuǎn)換返回的字符串值。

留下個(gè)問(wèn)題為什么空數(shù)組和空對(duì)象返回的是0和NaN? 有解釋的嗎 ,現(xiàn)在還摸不清
類(lèi)似于轉(zhuǎn)換數(shù)字的還有parseInt和parseFloat,有興趣的小伙伴可以了解了解,規(guī)則如下:
(1)忽略字符串前面的空格,直至找到第一個(gè)非空字符
(2)如果第一個(gè)字符不是數(shù)字符號(hào)或者負(fù)號(hào),返回NaN
(3)如果第一個(gè)字符是數(shù)字,則繼續(xù)解析直至字符串解析完畢或者遇到一個(gè)非數(shù)字符號(hào)為止
(4)如果上步解析的結(jié)果以0開(kāi)頭,則將其當(dāng)作八進(jìn)制來(lái)解析;如果以0x開(kāi)頭,則將其當(dāng)作十六進(jìn)制來(lái)解析
(5)如果指定radix參數(shù),則以radix為基數(shù)進(jìn)行解析
parseInt: 字符串中第一個(gè)小數(shù)點(diǎn)符號(hào)是有效的,另外parseFloat會(huì)忽略所有前導(dǎo)0,如果字符串包含一個(gè)可解析為整數(shù)的數(shù),則返回整數(shù)值而不是浮點(diǎn)數(shù)值。
- String() 將任何類(lèi)型的值轉(zhuǎn)換為字符串
toString方法是Object里面已經(jīng)有了的方法,而所有類(lèi)都是繼承Object,所以“所有對(duì)象都有這個(gè)方法,除了undefined和null”
(1)如果有toString()方法,則調(diào)用該方法(不傳遞radix參數(shù))并返回結(jié)果
(2)因?yàn)閚ull和undefine 沒(méi)有toString() ,所以如果是null,返回”null”如果是undefined,返回”undefined”

差不多了解到這 顯示轉(zhuǎn)換就完了,接下來(lái)就看看比較難理解的隱式轉(zhuǎn)換吧,腦袋都要繞蒙了。。。
隱式轉(zhuǎn)換
我大概總結(jié)了幾種發(fā)生隱式轉(zhuǎn)換的情況:
- 運(yùn)算操作符(遞增遞減呀++ --,一元加 +a,一元減- a)
在對(duì)非數(shù)值應(yīng)用運(yùn)算操作符操作時(shí),該操作符會(huì)像Number()轉(zhuǎn)型函數(shù)一樣對(duì)這個(gè)值執(zhí)行轉(zhuǎn)換

- 乘性操作符(乘法,除法,求模)
如果參與乘性操作數(shù)不是數(shù)值,后臺(tái)會(huì)先使用Number()轉(zhuǎn)型函數(shù)將其轉(zhuǎn)換為數(shù)值。

- 最常見(jiàn)的加減操作符
當(dāng)是加法時(shí),規(guī)則如下
(1)如果兩個(gè)操作數(shù)都是數(shù)值,執(zhí)行常規(guī)的加法計(jì)算
(2)如果有一個(gè)操作數(shù)是字符串:會(huì)進(jìn)行字符串拼接(另外一個(gè)操作數(shù)會(huì)轉(zhuǎn)為字符串)
(3)如果有一個(gè)操作數(shù)是對(duì)象、數(shù)值或布爾值,則調(diào)用它們的toString()方法取得相應(yīng)的字符串值,在應(yīng)用上述的字符串規(guī)則。對(duì)于undefined和null,則分別調(diào)用String()函數(shù)并取得字符串"undefined"和"null"
當(dāng)是減法時(shí)
(1)如果兩個(gè)操作數(shù)都是數(shù)值,執(zhí)行常規(guī)的減法計(jì)算
(2)如果有一個(gè)操作數(shù)是字符串、布爾值、null或undefined,先在后臺(tái)調(diào)用Number()函數(shù)將其轉(zhuǎn)換為數(shù)值,再計(jì)算,如果轉(zhuǎn)換結(jié)果是NaN,則結(jié)果是NaN
(3)如果有一個(gè)操作數(shù)是對(duì)象,則調(diào)用對(duì)象的valueOf()方法以取得表示該對(duì)象的數(shù)值,如果得到的值是NaN,則結(jié)果就是NaN。如果對(duì)象沒(méi)有valueOf()方法,則調(diào)用toString()方法

需要注意js中的浮點(diǎn)數(shù)運(yùn)算,精度不準(zhǔn)確
- 邏輯操作
1.對(duì)象和布爾值比較
對(duì)象和布爾值進(jìn)行比較時(shí),對(duì)象先轉(zhuǎn)換為字符串,然后再轉(zhuǎn)換為數(shù)字,布爾值直接轉(zhuǎn)換為數(shù)字
[] == true``; //false []轉(zhuǎn)換為字符串'',然后轉(zhuǎn)換為數(shù)字0,true轉(zhuǎn)換為數(shù)字1,所以為false
2. 對(duì)象和字符串比較
對(duì)象和字符串進(jìn)行比較時(shí),對(duì)象轉(zhuǎn)換為字符串,然后兩者進(jìn)行比較。
[1,2,3] == '1,2,3' // true [1,2,3]轉(zhuǎn)化為'1,2,3',然后和'1,2,3', so結(jié)果為true;
3. 對(duì)象和數(shù)字比較
對(duì)象和數(shù)字進(jìn)行比較時(shí),對(duì)象先轉(zhuǎn)換為字符串,然后轉(zhuǎn)換為數(shù)字,再和數(shù)字進(jìn)行比較。
[1] == 1; // true對(duì)象先轉(zhuǎn)換為字符串再轉(zhuǎn)換為數(shù)字,二者再比較 [1] => '1' => 1 所以結(jié)果為true`
4. 字符串和數(shù)字比較
字符串和數(shù)字進(jìn)行比較時(shí),字符串轉(zhuǎn)換成數(shù)字,二者再比較。
'1' == 1 // true
5. 字符串和布爾值比較
字符串和布爾值進(jìn)行比較時(shí),二者全部轉(zhuǎn)換成數(shù)值再比較。
'1' == true``; // true
6. 布爾值和數(shù)字比較
布爾值和數(shù)字進(jìn)行比較時(shí),布爾轉(zhuǎn)換為數(shù)字,二者比較。
true == 1 // true
7. 對(duì)象和對(duì)象比較
如果兩個(gè)操作數(shù)都是對(duì)象,則比較它們是不是同一個(gè)對(duì)象,如果兩個(gè)操作數(shù)都指向同一個(gè)對(duì)象,則相等操作符返回 true;否則, 返回false
還有一些if(),while,for循環(huán)這些都會(huì)觸發(fā)隱式轉(zhuǎn)換
好,我們現(xiàn)在看幾道題鞏固一下
[] == false; // true 因?yàn)閷?duì)象 => 字符串 => 數(shù)值 =>0 false轉(zhuǎn)換為數(shù)字0
![] == false; //true 因?yàn)榈诙€(gè)前邊多了個(gè)!,則直接轉(zhuǎn)換為布爾值再取反,故! []這個(gè)[] => true 取反為false
總結(jié)一下:[] == ! [] -> [] == false -> [] == 0 -> '' == 0 -> 0 == 0 -> true
注意哦 ! 的優(yōu)先級(jí)是大于 == 的
[] == [] //false
{} == {} //false
這個(gè)大家就應(yīng)該比較能理解 它們是獨(dú)立的2個(gè)對(duì)象,占了2份內(nèi)存空間, 那么肯定不相等了呀
undefind == null // true
[] == ![] // true
//! [] 運(yùn)算后的結(jié)果就是 false 就變成 []==false 所以返回true
{} == !{} // false
// 我們知道{}.toString()會(huì)變成 NaN,所以{} == ! {} -> {} == false -> {} == 0 -> NaN == 0 -> false
面試題來(lái)了哦
if([] == false) {console.log(1);};
if ([]) {console.log(2);};
if ({} == false ) {console.log(3);};
if ({}) {console.log(4);};
if ([1] == [1]) {console.log(5);};
大家做出來(lái)了吧 結(jié)果很簡(jiǎn)單: 1 2 4
第一個(gè)不用解釋了吧
第二個(gè)在if(condition)里會(huì)自動(dòng)把里面的利用Boolean()轉(zhuǎn)變,而B(niǎo)oolean任意一個(gè)對(duì)象都是true,所以打印
第三個(gè){}和boolean比較,對(duì)象最后會(huì)轉(zhuǎn)成數(shù)字和false比較,{}就變成了NaN,NaN與任何值都不相等,所以條件不成立
第四個(gè)和第二個(gè)同理
第五個(gè)我們知道對(duì)象除非指針一樣,否則它就是兩個(gè)不同的對(duì)象,所以條件不成立
至于比較繁繞的就看個(gè)人理解造化了 QaQ