JavaScript 是一種動態(tài)類型語言慢叨,變量沒有類型限制寺渗,可以隨時賦予任意值历涝。
例如:
var a = 10; // 創(chuàng)建一個變量a,并且賦值為10
a = "hello,world!"; // 將"hello,world"重新賦值給變量a淀零,這樣a就由number變?yōu)閟tring
再來看下面這個案例:
var x = y ? 1 : 'a';
上面代碼中挽绩,變量x
到底是數(shù)值還是字符串,取決于另一個變量y
的值驾中。y
為true
時唉堪,x
是一個數(shù)值;y
為false
時哀卫,x
是一個字符串巨坊。這意味著,x
的類型沒法在編譯階段就知道此改,必須等到運行時才能知道趾撵。
雖然變量的數(shù)據(jù)類型是不確定的,但是各種運算符對數(shù)據(jù)類型是有要求的。如果運算符發(fā)現(xiàn)占调,運算子的類型與預(yù)期不符暂题,就會自動轉(zhuǎn)換類型。比如究珊,減法運算符預(yù)期左右兩側(cè)的運算子應(yīng)該是數(shù)值薪者,如果不是,就會自動將它們轉(zhuǎn)為數(shù)值剿涮。
'4' - '3' // 1
上面代碼中言津,雖然是兩個字符串相減,但是依然會得到結(jié)果數(shù)值1
取试,原因就在于 JavaScript 將運算子自動轉(zhuǎn)為了數(shù)值悬槽。
在章節(jié),我們將會先來講解手動強制類型轉(zhuǎn)換數(shù)據(jù)類型
瞬浓,接著會說到數(shù)據(jù)類型的自動轉(zhuǎn)換規(guī)則
初婆。
強制類型轉(zhuǎn)換
強制轉(zhuǎn)換主要指使用Number()
、String()
和Boolean()
三個函數(shù)猿棉,手動將各種類型的值磅叛,分別轉(zhuǎn)換成數(shù)字、字符串或者布爾值萨赁。
Number()
使用Number
函數(shù)弊琴,可以將任意類型的值轉(zhuǎn)化成數(shù)值。
下面分成兩種情況討論位迂,一種是參數(shù)是原始類型的值访雪,另一種是參數(shù)是對象。
原始類型值:
下面通過案例來演示一下原始類型值轉(zhuǎn)換為Number類型的規(guī)則:
// 數(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ù)會自動過濾一個字符串前導(dǎo)和后綴的空格泻帮。
對象:
簡單的規(guī)則是精置,Number方法的參數(shù)是對象時,將返回NaN锣杂,除非是包含單個數(shù)值的數(shù)組脂倦。
Number({a: 1}) // NaN
Number([1, 2, 3]) // NaN
Number([5]) // 5
String()
String
函數(shù)可以將任意類型的值轉(zhuǎn)化成字符串,轉(zhuǎn)換規(guī)則如下元莫。
(1)原始類型值
- 數(shù)值:轉(zhuǎn)為相應(yīng)的字符串赖阻。
- 字符串:轉(zhuǎn)換后還是原來的值。
- 布爾值:true轉(zhuǎn)為字符串"true"踱蠢,false轉(zhuǎn)為字符串"false"火欧。
- undefined:轉(zhuǎn)為字符串"undefined"棋电。
- null:轉(zhuǎn)為字符串"null"。
String(123) // "123"
String('abc') // "abc"
String(true) // "true"
String(undefined) // "undefined"
String(null) // "null"
(2)對象:
String
方法的參數(shù)如果是對象苇侵,返回一個類型字符串赶盔;如果是數(shù)組,返回該數(shù)組的字符串形式榆浓。
String({a: 1}) // "[object Object]"
String([1, 2, 3]) // "1,2,3"
Boolean()
Boolean()
函數(shù)可以將任意類型的值轉(zhuǎn)為布爾值于未。
它的轉(zhuǎn)換規(guī)則相對簡單:除了以下五個值的轉(zhuǎn)換結(jié)果為false
,其他的值全部為true
陡鹃。
undefined
null
-
0
(包含-0
和+0
) NaN
-
''
(空字符串)
Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean(NaN) // false
Boolean('') // false
當(dāng)然烘浦,true
和false
這兩個布爾值不會發(fā)生變化。
Boolean(true) // true
Boolean(false) // false
注意萍鲸,所有對象(包括空對象)的轉(zhuǎn)換結(jié)果都是true
谎倔,甚至連false
對應(yīng)的布爾對象new Boolean(false)
也是true
Boolean({}) // true
Boolean([]) // true
Boolean(new Boolean(false)) // true
所有對象的布爾值都是true
,這是因為 JavaScript 語言設(shè)計的時候猿推,出于性能的考慮,如果對象需要計算才能得到布爾值捌肴,對于obj1 && obj2
這樣的場景蹬叭,可能會需要較多的計算。為了保證性能状知,就統(tǒng)一規(guī)定秽五,對象的布爾值為true
。
自動類型轉(zhuǎn)換
上面說完了強制類型轉(zhuǎn)換饥悴,再來說下自動類型轉(zhuǎn)換坦喘,它是以強制類型轉(zhuǎn)換為基礎(chǔ)的。
遇到以下三種情況時西设,JavaScript 會自動轉(zhuǎn)換數(shù)據(jù)類型瓣铣,即轉(zhuǎn)換是自動完成的,用戶不可見贷揽。
第一種情況棠笑,不同類型的數(shù)據(jù)互相運算。
123 + 'abc' // "123abc"
第二種情況禽绪,對非布爾值類型的數(shù)據(jù)求布爾值蓖救。
if ('abc') {
console.log('hello')
}
第三種情況,對非數(shù)值類型的值使用一元運算符(即+
和-
)印屁。
var a = "10";
console.log(+ a,typeof +a); // 10 "number"
+ {foo: 'bar'} // NaN
- [1, 2, 3] // NaN
自動轉(zhuǎn)換的規(guī)則是這樣的:預(yù)期什么類型的值循捺,就調(diào)用該類型的轉(zhuǎn)換函數(shù)。比如雄人,某個位置預(yù)期為字符串从橘,就調(diào)用String
函數(shù)進行轉(zhuǎn)換。如果該位置即可以是字符串,也可能是數(shù)值洋满,那么默認轉(zhuǎn)為數(shù)值晶乔。
由于自動轉(zhuǎn)換具有不確定性,而且不易除錯牺勾,建議在預(yù)期為布爾值正罢、數(shù)值、字符串的地方驻民,全部使用Boolean
翻具、Number
和String
函數(shù)進行顯式轉(zhuǎn)換。
自動轉(zhuǎn)換為布爾值
JavaScript 遇到預(yù)期為布爾值的地方(比如if
語句的條件部分)回还,就會將非布爾值的參數(shù)自動轉(zhuǎn)換為布爾值裆泳。系統(tǒng)內(nèi)部會自動調(diào)用Boolean
函數(shù)。
因此除了以下五個值柠硕,其他都是自動轉(zhuǎn)為true
工禾。
undefined
null
-
+0
或-0
NaN
-
''
(空字符串)
下面這個例子中,條件部分的每個值都相當(dāng)于false
蝗柔,使用否定運算符后闻葵,就變成了true
。
if ( !undefined
&& !null
&& !0
&& !NaN
&& !''
) {
console.log('true');
} // true
下面兩種寫法癣丧,有時也用于將一個表達式轉(zhuǎn)為布爾值槽畔。它們內(nèi)部調(diào)用的也是Boolean
函數(shù)。
// 寫法一
expression ? true : false
// 寫法二
!! expression
自動轉(zhuǎn)換為字符串
JavaScript 遇到預(yù)期為字符串的地方胁编,就會將非字符串的值自動轉(zhuǎn)為字符串厢钧。具體規(guī)則是,先將復(fù)合類型的值轉(zhuǎn)為原始類型的值嬉橙,再將原始類型的值轉(zhuǎn)為字符串早直。
字符串的自動轉(zhuǎn)換,主要發(fā)生在字符串的加法運算時憎夷。當(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"
這種自動轉(zhuǎn)換很容易出錯祥得。
var obj = {
width: '100'
};
obj.width + 20 // "10020"
上面代碼中,開發(fā)者可能期望返回120
蒋得,但是由于自動轉(zhuǎn)換级及,實際上返回了一個字符10020
。
自動轉(zhuǎn)換為數(shù)值
JavaScript 遇到預(yù)期為數(shù)值的地方额衙,就會將參數(shù)值自動轉(zhuǎn)換為數(shù)值饮焦。系統(tǒng)內(nèi)部會自動調(diào)用Number
函數(shù)怕吴。
除了加法運算符(+
)有可能把運算子轉(zhuǎ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
null + 1 // 1
undefined + 1 // NaN
上面代碼中转绷,運算符兩側(cè)的運算子,都被轉(zhuǎn)成了數(shù)值硼啤。
注意:
null
轉(zhuǎn)為數(shù)值時為0
议经,而undefined
轉(zhuǎn)為數(shù)值時為NaN
。
一元運算符也會把運算子轉(zhuǎn)成數(shù)值谴返。
+'abc' // NaN
-'abc' // NaN
+true // 1
-false // 0
字符轉(zhuǎn)數(shù)值
如果對非String使用parseInt()或parseFloat()煞肾,它會先將其轉(zhuǎn)化為String,然后再操作
-
parseFloat();除了能識別小數(shù)點之外嗓袱,其他規(guī)則和parseInt相同
image.png -
parseInt();從左向右依次檢測籍救,遇到非數(shù)字的字符,停止轉(zhuǎn)換渠抹,如果第一位就非數(shù)字蝙昙,那么NaN,不能識別小數(shù)點梧却,相當(dāng)于是只能轉(zhuǎn)整數(shù)耸黑,取整
image.png -
Math.round();取最接近的整數(shù),同時嚴(yán)格轉(zhuǎn)換篮幢,任何位置不允許出現(xiàn)非數(shù)字的字符,但存在一些問題
所謂“四舍六入五成雙”为迈,在百度百科上給的解釋是:也即“4舍6入5湊偶”這里“四”是指≤4 時舍去三椿,"六"是指≥6時進上,"五"指的是根據(jù)5后面的數(shù)字來定葫辐,當(dāng)5后有數(shù)時搜锰,舍5入1;當(dāng)5后無有效數(shù)字時耿战,需要分兩種情況來講:①5前為奇數(shù)蛋叼,舍5入1;②5前為偶數(shù)剂陡,舍5不進狈涮。(0是最小的偶數(shù)) 。
image.png -
Number();嚴(yán)格轉(zhuǎn)換鸭栖,整體轉(zhuǎn)換歌馍,能識別小數(shù)點(結(jié)合上面的強制轉(zhuǎn)換)
image.png
數(shù)值轉(zhuǎn)字符
調(diào)用xxx的yyy()方法,就是xxx.yyy()晕鹊;
-
toString()方法;原模原樣轉(zhuǎn)換松却,相當(dāng)于直接套個引號暴浦,
null和undefined這兩個值沒有toString()方法;
image.png 調(diào)用String()函數(shù),并將被轉(zhuǎn)化的數(shù)據(jù)作為
參數(shù)
傳遞給函數(shù)(結(jié)合上面的強制轉(zhuǎn)換)-
toFixed(n);四舍五入晓锻,保留n位小數(shù)
最近發(fā)現(xiàn)JS當(dāng)中toFixed()方法存在一些問題歌焦,采用原生的Number對象的原型對象上的toFixed()方法時,規(guī)則并不是所謂的“四舍五入”或者是“四舍六入五成雙”砚哆,所謂“四舍六入五成雙”独撇,在百度百科上給的解釋是:也即“4舍6入5湊偶”這里“四”是指≤4 時舍去,"六"是指≥6時進上窟社,"五"指的是根據(jù)5后面的數(shù)字來定券勺,當(dāng)5后有數(shù)時,舍5入1灿里;當(dāng)5后無有效數(shù)字時关炼,需要分兩種情況來講:①5前為奇數(shù),舍5入1匣吊;②5前為偶數(shù)儒拂,舍5不進。(0是最小的偶數(shù)) 色鸳。
image.png