一空镜、概述
JS是一種動態(tài)類型語言浩淘,變量沒有類型限制,可以隨時賦予任何值吴攒。
雖然變量沒有確切的類型张抄,但是數(shù)據(jù)本身和各種運(yùn)算符是有類型的。如果運(yùn)算符發(fā)現(xiàn)洼怔,數(shù)據(jù)類型與預(yù)期不符署惯,就會自動轉(zhuǎn)換類型。比如镣隶,減法運(yùn)算符兩側(cè)的運(yùn)算子應(yīng)該是數(shù)值极谊,如果不是,就會自動將它們轉(zhuǎn)為數(shù)值矾缓。
二怀酷、強(qiáng)制轉(zhuǎn)換
強(qiáng)制轉(zhuǎn)換主要指使用Number、String嗜闻、Boolean
三個構(gòu)造函數(shù)蜕依,手動將各種類型的值,轉(zhuǎn)換成數(shù)字、字符串或者布爾值样眠。
2.1友瘤、Number()
使用Number
函數(shù),可以將任意類型的值轉(zhuǎn)化成數(shù)值檐束。
下面分成兩種情況討論辫秧,一種是參數(shù)是原始類型的值,另一種是參數(shù)是對象被丧。
(1)盟戏、原始類型值的轉(zhuǎn)換規(guī)則
原始類型值主要是數(shù)值、字符串甥桂、布爾值柿究、undefined
和null
,它們都能被Number
轉(zhuǎn)成數(shù)值或NaN
黄选。
// 數(shù)值:轉(zhuǎn)換后還是原來的值
Number(324) // 324
// 字符串:如果可以被解析為數(shù)值蝇摸,則轉(zhuǎn)換為相應(yīng)的數(shù)值
Number('324') // 324
// 字符串:如果不可以被解析為數(shù)值,返回NaN
Number('324abc') // NaN
// 空字符串轉(zhuǎn)為0
Number('') // 0
// 布爾值:true 轉(zhuǎn)成1办陷,false 轉(zhuǎn)成0
Number(true) // 1
Number(false) // 0
// undefined:轉(zhuǎn)成 NaN
Number(undefined) // NaN
// null:轉(zhuǎn)成0
Number(null) // 0
Number
函數(shù)將字符串轉(zhuǎn)為數(shù)值貌夕,要比parseInt
函數(shù)嚴(yán)格很多∶窬担基本上啡专,只要有一個字符無法轉(zhuǎn)成數(shù)值,整個字符串就會被轉(zhuǎn)為NaN
殃恒。
parseInt('42 cats') // 42
Number('42 cats') // NaN
上面代碼中植旧,parseInt
逐個解析字符,而Number
函數(shù)整體轉(zhuǎn)換字符串的類型离唐。
另外病附,Number
函數(shù)會自動過濾一個字符串前導(dǎo)和后綴的空格。
Number('\t\v\r12.34\n') // 12.34
(2)亥鬓、對象的轉(zhuǎn)換規(guī)則
簡單來說完沪,Number
方法的參數(shù)是對象時,將返回NaN
嵌戈。
Number({a: 1}); //NaN
Number([1, 2, 3]); //NaN
//注意數(shù)組有點(diǎn)不一樣
Number([1]); //1
Number([]); //0
實(shí)際上覆积,Number
背后的真正規(guī)則復(fù)雜得多,內(nèi)部處理步驟如下:
1熟呛、調(diào)用對象自身的
valueOf
方法宽档。如果返回原始類型的值,則直接對該值使用Number
函數(shù)庵朝,不再進(jìn)行后續(xù)步驟吗冤。
2又厉、如果valueOf
方法返回的還是對象,則改為調(diào)用對象自身的toString
方法椎瘟。如果返回原始類型的值覆致,則對該值使用Number
函數(shù),不再進(jìn)行后續(xù)步驟肺蔚。
3煌妈、如果toString
方法返回的是對象,就報錯宣羊。
注意:自己定義valueOf
和toString
方法璧诵,不過一般來說對象的valueOf
方法返回對象本身,所以一般總是會調(diào)用toString
方法段只。
2.2腮猖、String()
使用String
函數(shù)鉴扫,可以將任何類型的值轉(zhuǎn)化成字符串赞枕。
規(guī)則如下:
(1)、原始類型值的轉(zhuǎn)換規(guī)則
數(shù)值:轉(zhuǎn)為相應(yīng)的字符串坪创。
字符串:就是簡單的輸入輸出炕婶,值不變
布爾值:true
轉(zhuǎn)為"true"
,false
變?yōu)?code>"false"莱预。
undefined:轉(zhuǎn)為"undefined"
柠掂。
null:轉(zhuǎn)為"null"
。
(2)依沮、對象的轉(zhuǎn)換規(guī)則
String
方法的參數(shù)如果是對象涯贞,返回一個類型字符串;如果是數(shù)組危喉,返回該數(shù)組的字符串形式宋渔。
String({a: 1}); //"[object Object]"
String([1, 2, 3]); //"1,2,3"
String
方法背后的轉(zhuǎn)換規(guī)則,與Number
方法基本相同辜限,只是互換了valueOf
方法和toString
方法的執(zhí)行順序皇拣。
1、先調(diào)用對象自身的
toString
方法薄嫡。如果返回原始類型的值氧急,則對該值使用String
函數(shù),不再進(jìn)行以下步驟毫深。
2吩坝、如果toString
方法返回的是對象,再調(diào)用valueOf
方法哑蔫。如果返回原始類型的值钉寝,則對該值使用String
函數(shù)手素,不再進(jìn)行以下步驟。
3瘩蚪、如果valueOf
方法返回的是對象泉懦,就報錯。
下面是一個例子疹瘦。
String({a: 1});
// "[object Object]"
// 等同于
String({a: 1}.toString());
// "[object Object]"
上面代碼先調(diào)用對象的toString
方法崩哩,發(fā)現(xiàn)返回的是字符串[object Object]
,就不再調(diào)用valueOf
方法了言沐。
2.3邓嘹、Boolean()
使用Boolean
函數(shù),可以將任意類型的變量轉(zhuǎn)為布爾值险胰。
它的轉(zhuǎn)換規(guī)則相對簡單:除了以下六個值的轉(zhuǎn)換結(jié)果為false
汹押,其他的值全部為true
。
undefined
null
false
0
NaN
""或''(空字符串起便,引號之間沒有空格)
注意:所有對象(包括空對象)的轉(zhuǎn)換結(jié)果都是true
棚贾。
三、自動轉(zhuǎn)換
自動轉(zhuǎn)換榆综,它是以強(qiáng)制轉(zhuǎn)換為基礎(chǔ)的妙痹。
自動轉(zhuǎn)換的規(guī)則是這樣的:預(yù)期什么類型的值,就調(diào)用該類型的轉(zhuǎn)換函數(shù)鼻疮。
比如怯伊,某個位置預(yù)期為字符串,就調(diào)用String
函數(shù)進(jìn)行轉(zhuǎn)換判沟。如果該位置既可以是字符串耿芹,也可能是數(shù)值,那么默認(rèn)轉(zhuǎn)為數(shù)值挪哄。
由于自動轉(zhuǎn)換具有不確定性吧秕,而且不易除錯,建議在預(yù)期為布爾值中燥、數(shù)值寇甸、字符串的地方,全部使用Boolean疗涉、Number和String
函數(shù)進(jìn)行顯式轉(zhuǎn)換拿霉。
3.1、自動轉(zhuǎn)換為布爾值
當(dāng)JS遇到預(yù)期為布爾值的地方(比如if
語句的條件部分)咱扣,就會將非布爾值的參數(shù)自動轉(zhuǎn)換為布爾值绽淘。系統(tǒng)內(nèi)部會自動調(diào)用Boolean
函數(shù)。
因此除了上面提到的六個值闹伪,其他都是自動轉(zhuǎn)為true
沪铭。
下面這個例子中壮池,條件部分的每個值都相當(dāng)于false
,使用否定運(yùn)算符后杀怠,就變成了true
椰憋。
if ( !undefined && !null && !0 && !NaN && !'') {
console.log('true');
} // true
下面兩種寫法,有時也用于將一個表達(dá)式轉(zhuǎn)為布爾值赔退。它們內(nèi)部調(diào)用的也是Boolean
函數(shù)橙依。
// 寫法一
expression ? true : false
// 寫法二
!! expression
3.2、自動轉(zhuǎn)換為字符串
當(dāng)JS遇到預(yù)期為字符串的地方硕旗,就會將非字符串的數(shù)據(jù)自動轉(zhuǎn)為字符串窗骑。系統(tǒng)內(nèi)部會自動調(diào)用String
函數(shù)。
字符串的自動轉(zhuǎn)換漆枚,主要發(fā)生在加法運(yùn)算時创译。當(dāng)一個值為字符串,另一個值為非字符串墙基,則后者轉(zhuǎn)為字符串软族。
'5' + 1 // '51'
'5' + true // "5true"
'5' + false // "5false"
'5' + {} // "5[object Object]"
'5' + [] // "5"
'5' + function (){} // "5function (){}"
'5' + undefined // "5undefined"
'5' + null // "5null"
3.2、自動轉(zhuǎn)換為數(shù)值
當(dāng)JS遇到預(yù)期為數(shù)值的地方碘橘,就會將參數(shù)值自動轉(zhuǎn)換為數(shù)值互订。系統(tǒng)內(nèi)部會自動調(diào)用Number
函數(shù)。
除了加法運(yùn)算符有可能把運(yùn)算子轉(zhuǎn)為字符串痘拆,其他運(yùn)算符都會把運(yùn)算子自動轉(zhuǎn)成數(shù)值。
'5' - '2' // 3
'5' * '2' // 10
true - 1 // 0
false - 1 // -1
'1' - 1 // 0
'5' * [] // 0
false / '5' // 0
'abc' - 1 // NaN
上面代碼中氮墨,運(yùn)算符兩側(cè)的運(yùn)算子纺蛆,都被轉(zhuǎn)成了數(shù)值。
一元運(yùn)算符也會把運(yùn)算子轉(zhuǎn)成數(shù)值规揪。
+'abc' // NaN
-'abc' // NaN
+true // 1
-false // 0
(本系列下一節(jié)為 — 錯誤處理機(jī)制)