JavaScript數(shù)據(jù)類型轉(zhuǎn)換

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的值驾中。ytrue時唉堪,x是一個數(shù)值;yfalse時哀卫,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)然烘浦,truefalse這兩個布爾值不會發(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翻具、NumberString函數(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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末社痛,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子命雀,更是在濱河造成了極大的恐慌蒜哀,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吏砂,死亡現(xiàn)場離奇詭異撵儿,居然都是意外死亡,警方通過查閱死者的電腦和手機狐血,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門淀歇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人匈织,你說我怎么就攤上這事浪默。” “怎么了缀匕?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵纳决,是天一觀的道長。 經(jīng)常有香客問我乡小,道長岳链,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任劲件,我火速辦了婚禮掸哑,結(jié)果婚禮上约急,老公的妹妹穿的比我還像新娘。我一直安慰自己苗分,他們只是感情好厌蔽,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著摔癣,像睡著了一般奴饮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上择浊,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天戴卜,我揣著相機與錄音,去河邊找鬼琢岩。 笑死投剥,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的担孔。 我是一名探鬼主播江锨,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼糕篇!你這毒婦竟也來了啄育?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤拌消,失蹤者是張志新(化名)和其女友劉穎挑豌,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體墩崩,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡浮毯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了泰鸡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡壳鹤,死狀恐怖盛龄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情芳誓,我是刑警寧澤余舶,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站锹淌,受9級特大地震影響匿值,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赂摆,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一挟憔、第九天 我趴在偏房一處隱蔽的房頂上張望钟些。 院中可真熱鬧,春花似錦绊谭、人聲如沸政恍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽篙耗。三九已至,卻和暖如春宪赶,著一層夾襖步出監(jiān)牢的瞬間宗弯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工搂妻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蒙保,地道東北人。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓叽讳,卻偏偏與公主長得像追他,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子岛蚤,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355