前言:js的類型轉(zhuǎn)換真是容易讓人一頭霧水,接下來(lái)我將會(huì)好好整理一下坏为。
原始值到原始值(數(shù)字陨囊,字符串,布爾值)的轉(zhuǎn)換
原始值轉(zhuǎn)化為布爾值剧辐,所有的假值("undefined","null",0,-0,NaN,"")都會(huì)被轉(zhuǎn)化false,其他都會(huì)被轉(zhuǎn)化為true.
原始值轉(zhuǎn)換為字符串相當(dāng)于加""
-
原始值轉(zhuǎn)化為數(shù)字寒亥,布爾轉(zhuǎn)文字:true --> 1,false --> 2
字符串轉(zhuǎn)數(shù)字,只有字符串中都是以數(shù)字表示的荧关,就可以直接轉(zhuǎn)換為字符串溉奕,如果兩個(gè)數(shù)字間有空格的話,那么轉(zhuǎn)換結(jié)果就是NaN.+"123" //123 +"1 3" // NaN
原始值到對(duì)象的轉(zhuǎn)換
- null和undefined會(huì)直接報(bào)錯(cuò)忍啤。
- 原始值會(huì)通過(guò)調(diào)用String(),Number(),Boolean()構(gòu)造函數(shù)加勤,轉(zhuǎn)換為他們各自的包裝對(duì)象。
對(duì)象到原始值的轉(zhuǎn)換
- 對(duì)象轉(zhuǎn)換為布爾值都是true
- 對(duì)象到字符串
- 如果對(duì)象有toString()方法同波,就調(diào)用toString()方法鳄梅,如果這個(gè)方法返回原始值,就將這個(gè)對(duì)象轉(zhuǎn)化為字符串参萄。
- 如果對(duì)象沒(méi)有toString()方法或者該方法返回的不是原始值卫枝,那么就會(huì)調(diào)用該對(duì)象的valueOf()方法,如果存在就調(diào)用這個(gè)方法讹挎,如果返回值是字符串就轉(zhuǎn)換為字符串校赤。
- 否則就報(bào)錯(cuò)。
復(fù)習(xí)一下Object的屬性和方法
Constructor:保存著用于創(chuàng)建當(dāng)前對(duì)象的函數(shù)筒溃。
hasOwnProperty(property):用于檢查給定的屬性在當(dāng)前實(shí)例中(不包括原型)是否存在马篮。
isPrototypeOf(object):用于檢查傳入的對(duì)象是否是另外一個(gè)對(duì)象的原型。
propertyIsEnumberable(property):用來(lái)檢查給定的屬性能用for-in語(yǔ)句來(lái)枚舉怜奖。
toLocaleString():返回對(duì)象的字符串表示浑测,該字符串與執(zhí)行環(huán)境地區(qū)相對(duì)應(yīng)
toString():返回對(duì)象的字符串表示。
-
valueOf():返回對(duì)象的字符串表示,數(shù)值或者布爾值表示迁央,很多時(shí)候與toString()方法的返回值相同掷匠。
toString
valueOf1.toString()//Uncaught SyntaxError: Invalid or unexpected token 1..toString()//"1" 1...toString()//Uncaught SyntaxError: Unexpected token . 2.0.toString()//"2"
==運(yùn)算符怎么進(jìn)行類型轉(zhuǎn)換
- 如果一個(gè)值是null,另一個(gè)值undefined,則相等。
- 如果一個(gè)是字符串岖圈,另一個(gè)是數(shù)字讹语,則要把字符串轉(zhuǎn)換為數(shù)字,進(jìn)行比較蜂科。
- 如果任意值是true,則要把true轉(zhuǎn)換為1再進(jìn)行比較顽决,如果是false,則要把false轉(zhuǎn)換為0再進(jìn)行比較
- 如果一個(gè)是對(duì)象导匣,另一個(gè)數(shù)值或字符串才菠,把對(duì)象轉(zhuǎn)換為基礎(chǔ)類型的值在進(jìn)行比較(toString,valueOf())。
+運(yùn)算符如何進(jìn)行類型轉(zhuǎn)換贡定。
-
如果作為一元運(yùn)算符就是轉(zhuǎn)化為數(shù)字赋访,常常用來(lái)將字符串轉(zhuǎn)化為數(shù)字。
+“2” //2
如果作為二元運(yùn)算符就有兩種轉(zhuǎn)換方式
- 兩邊如果有字符串缓待,就會(huì)將另外一家轉(zhuǎn)化為字符串進(jìn)行拼接进每。
- 如果兩邊沒(méi)有字符串,兩邊都會(huì)轉(zhuǎn)化數(shù)字相加命斧,對(duì)象也會(huì)根據(jù)錢(qián)買(mǎi)你的方法轉(zhuǎn)化為原始值數(shù)字田晚。
-
如果其中的一個(gè)操作數(shù)是對(duì)象,則將對(duì)象轉(zhuǎn)換為原始值国葬,日期對(duì)象會(huì)通過(guò)toString()贤徒,其他對(duì)象會(huì)通過(guò)valueOf()方法進(jìn)行轉(zhuǎn)換,但是大多數(shù)對(duì)象都是不具備可用的valueOf()方法汇四,所以還是會(huì)通過(guò)toString()方法執(zhí)行轉(zhuǎn)換接奈。
image.png
實(shí)戰(zhàn)
-
[] + [] //" "
-
首先左邊的[]調(diào)用valueOf()方法,發(fā)現(xiàn)還是[],所以去調(diào)用toString()方法通孽。
[].toString() //" "
有一邊是字符串序宦,所以左邊的也要轉(zhuǎn)化為字符串,也變成"",
"" + "" ="" //空字符串+空字符串 = 空字符串
-
(! + [] + [] + ![]).length
-
因?yàn)?是一元運(yùn)算符背苦,所以我們得出了這樣的運(yùn)算規(guī)則
image.png -
!后面的+[]會(huì)變成數(shù)字0,![]會(huì)變成”false"那么我們就會(huì)得到
!0 + [] + “false"
-
因?yàn)橛凶址拇嬖诨グ疲裕?轉(zhuǎn)換為字符串就是"true",[]轉(zhuǎn)換為字符串就是“”
那么我們就會(huì)得到“true"+""+"false" //”truefalse“
-
所以
( ”truefalse").length //9
參考文章:
https://mp.weixin.qq.com/s/wd8JLGtnsoQYfm3K7KXO0g
最近又在工作中遇到了一個(gè)類型轉(zhuǎn)換的坑!P屑痢秕噪!
更新
由上圖我們可以看到,左邊框是一個(gè)存在的世界厚宰,右邊框是一個(gè)空的世界腌巾。
只要拿左邊框的和右邊的比較,都會(huì)得到false.
N表示ToNumber操作,即將操作數(shù)轉(zhuǎn)為數(shù)字澈蝙。它是規(guī)范中的抽象操作吓坚,但我們可以用JS中的Number()函數(shù)來(lái)等價(jià)替代。
P表示ToPrimitive操作灯荧,即將操作數(shù)轉(zhuǎn)為原始類型的值凌唬。它也是規(guī)范中的抽象操作,同樣也可以翻譯成等價(jià)的JS代碼漏麦。不過(guò)稍微復(fù)雜一些,簡(jiǎn)單說(shuō)來(lái)况褪,對(duì)于一個(gè)對(duì)象obj:
- undefined == null撕贞,結(jié)果是true。且它倆與所有其他值比較的結(jié)果都是false测垛。
- String == Boolean捏膨,需要兩個(gè)操作數(shù)同時(shí)轉(zhuǎn)為Number。
- String/Boolean == Number食侮,需要String/Boolean轉(zhuǎn)為Number号涯。
- Object == Primitive,需要Object轉(zhuǎn)為Primitive(具體通過(guò)valueOf和toString方法)锯七。
ToPrimitive(obj)等價(jià)于:先計(jì)算obj.valueOf()链快,如果結(jié)果為原始值,則返回此結(jié)果眉尸;否則域蜗,計(jì)算obj.toString(),如果結(jié)果是原始值噪猾,則返回此結(jié)果霉祸;否則,拋出異常袱蜡。
//大坑
console.log ( [] == 0 );//true
console.log ( ! [] == 0 );//true
//神坑
console.log ( [] == ! [] );//true
console.log ( [] == [] );//false
//史詩(shī)級(jí)坑
console.log({} == !{});//false
console.log({} == {});//false
[]==[]丝蹭,兩個(gè)的地址都不一樣,肯定是false啦
讓我們用愉快的心情來(lái)從頭到尾看一下 [] == ![]的比較過(guò)程
下面是運(yùn)算符的優(yōu)先級(jí)
總結(jié)一下比較常用的符號(hào)的優(yōu)先級(jí)
( ) > !(邏輯非) > +坪蚁,-(一元加法奔穿,一元減法) > * ,/, % > ==,===
很明顯敏晤,取反的優(yōu)先級(jí)高于==(取反運(yùn)算符得到的結(jié)果是boolean值)