JavaScript中的類型轉(zhuǎn)換
JavaScript在處理不同類型的值時非常靈活。如果JavaScript需要布爾值,而您提供了其他類型的值,JavaScript會根據(jù)需要進(jìn)行轉(zhuǎn)換。一些值(稱為truthy值)會轉(zhuǎn)換為true,而另一些值(稱為falsy值)會轉(zhuǎn)換為false。對其他類型也適用同樣的原則:如果JavaScript需要一個字符串,它會將您提供的任何值轉(zhuǎn)換為字符串。如果JavaScript需要一個數(shù)字,它會嘗試將該值轉(zhuǎn)換為數(shù)字(如果無法轉(zhuǎn)換則為NaN)。
讓我們看一些示例:
1. 轉(zhuǎn)換和等式。?
JavaScript有兩個用于測試兩個值相等的運(yùn)算符。一個是嚴(yán)格等號運(yùn)算符(===),它不認(rèn)為不同類型的值相等。然而,由于JavaScript的靈活類型轉(zhuǎn)換,它還定義了寬松等號運(yùn)算符(==),它具有更靈活的等式概念。例如,以下比較都會返回true:
但請記住,僅因為一個值可以轉(zhuǎn)換為另一個值并不意味著它們相等。例如,如果在期望布爾值的上下文中使用undefined
,它將被轉(zhuǎn)換為false
。然而,這并不意味著undefined == false
。JavaScript運(yùn)算符和語句期望不同類型的值,并對這些目標(biāo)類型執(zhí)行轉(zhuǎn)換。if
語句將undefined
轉(zhuǎn)換為false
,但==
運(yùn)算符永遠(yuǎn)不會將其操作數(shù)轉(zhuǎn)換為布爾值。
(程序員的軟技能:ke.qq.com/course/6034346)
2. 顯式轉(zhuǎn)換。
雖然JavaScript會自動執(zhí)行許多類型的轉(zhuǎn)換,但在某些情況下,顯式轉(zhuǎn)換是必要的,或者出于代碼清晰性的考慮而優(yōu)先選擇。 執(zhí)行顯式類型轉(zhuǎn)換的最簡單方法是使用Boolean()
、Number()
和String()
函數(shù):
除了null
和undefined
之外的所有值都有一個toString()
方法,這個方法的結(jié)果通常與String()
函數(shù)的結(jié)果相同。
順便說一下,Boolean()
、Number()
和String()
函數(shù)也可以作為構(gòu)造函數(shù)與new
關(guān)鍵字一起使用。然而,這會創(chuàng)建與原始布爾值、數(shù)字和字符串值類似的“包裝”對象,這是JavaScript早期版本中的歷史遺留問題,現(xiàn)在不再需要。
一些JavaScript運(yùn)算符執(zhí)行隱式類型轉(zhuǎn)換,這可以用于類型轉(zhuǎn)換的目的。如果+
運(yùn)算符的一個操作數(shù)是字符串,它會將另一個操作數(shù)轉(zhuǎn)換為字符串。一元+
運(yùn)算符將其操作數(shù)轉(zhuǎn)換為數(shù)字,一元!
運(yùn)算符將其操作數(shù)轉(zhuǎn)換為布爾值,然后取反。這些事實(shí)導(dǎo)致了常見的類型轉(zhuǎn)換模式,例如:
格式化和解析數(shù)字是計算機(jī)程序中常見的錯誤來源,JavaScript提供了專門的函數(shù)和方法,以便更精確地控制從數(shù)字到字符串的轉(zhuǎn)換,反之亦然。Number
類定義了toString()
方法,它接受一個可選的參數(shù)來指定基數(shù)或底數(shù)。如果未提供此參數(shù), 默認(rèn)基數(shù)為10。但是,也可以將數(shù)字轉(zhuǎn)換為其他基數(shù)(2到36)。例如:
在處理金融或科學(xué)數(shù)據(jù)時,您可能需要控制結(jié)果字符串中的小數(shù)位數(shù)或有效數(shù)字,或者可能想使用指數(shù)表示法。Number
類提供了從數(shù)字到字符串的轉(zhuǎn)換的三種方法。toFixed()
將數(shù)字轉(zhuǎn)換為字符串,并允許您指定小數(shù)點(diǎn)后的位數(shù)。該方法不使用指數(shù)表示法。toExponential()
使用指數(shù)表示法將數(shù)字轉(zhuǎn)換為字符串,其中小數(shù)點(diǎn)前有一位數(shù)字,小數(shù)點(diǎn)后有指定數(shù)量的位數(shù)(比您指定的位數(shù)多一個有效數(shù)字)。toPrecision()
將數(shù)字轉(zhuǎn)換為具有指定數(shù)量有效數(shù)字的字符串。如果指定的有效數(shù)字不足以表示數(shù)字的整數(shù)部分,則使用指數(shù)表示法。請注意,這三種方法會根據(jù)需要進(jìn)行四舍五入或填充零。以下是一些示例:
如果將字符串傳遞給Number()
轉(zhuǎn)換函數(shù),它將嘗試將字符串解析為整數(shù)或浮點(diǎn)數(shù)文字。此函數(shù)僅適用于基數(shù)為10的整數(shù),并且不允許尾部非數(shù)字字符。parseInt()
和parseFloat()
函數(shù)(都不是任何類的方法,而是全局函數(shù))更具靈活性。parseInt()
僅解析整數(shù),而parseFloat()
解析整數(shù)和浮點(diǎn)數(shù)。如果字符串以"0x"或"0X"開頭,parseInt()
將其解析為十六進(jìn)制數(shù)。parseInt()
和parseFloat()
都會跳過前導(dǎo)空格,解析盡可能多的數(shù)字字符,并忽略后跟的任何非數(shù)字字符。如果第一個非空格字符不是有效的數(shù)字文字,則它們返回NaN
:
parseInt()
函數(shù)接受一個可選的第二個參數(shù),用于指定解析數(shù)字的基數(shù)(底數(shù))?;鶖?shù)的有效值為2到36。例如:
(程序員的軟技能:ke.qq.com/course/6034346)
3. 對象到原始值的轉(zhuǎn)換。
接下來,我們將討論JavaScript在將對象轉(zhuǎn)換為原始值時遵循的復(fù)雜規(guī)則。這些規(guī)則既冗長又有些復(fù)雜。
將JavaScript對象轉(zhuǎn)換為原始值的復(fù)雜性主要源于一些對象類型具有多個表示作為原始值的方式。例如,Date對象可以表示為字符串或時間戳。JavaScript為將對象轉(zhuǎn)換為原始值指定了三個基本算法。
(1) 字符串提示。該算法返回一個原始值,并在可能的情況下返回一個字符串。 (2) 數(shù)字提示。該算法返回一個原始值,并在可能的情況下返回一個數(shù)字。 (3) 默認(rèn)提示。該算法不偏好特定的原始值類型,并由類定義以指定其自己的轉(zhuǎn)換規(guī)則。除Date類外,所有內(nèi)置的JavaScript類型都實(shí)現(xiàn)了數(shù)字提示算法,而Date類實(shí)現(xiàn)了字符串提示算法。
讓我們深入探討這些算法在JavaScript中的使用。
從對象到布爾值的轉(zhuǎn)換。
將對象轉(zhuǎn)換為布爾值很簡單:所有對象都被轉(zhuǎn)換為true。請注意,這種轉(zhuǎn)換不需要前面提到的對象到原始值轉(zhuǎn)換算法;它直接適用于所有對象。這包括空數(shù)組,甚至包裝對象如new Boolean(false)
。
從對象到字符串的轉(zhuǎn)換。?
當(dāng)將對象轉(zhuǎn)換為字符串時,JavaScript首先使用字符串提示算法將其轉(zhuǎn)換為原始值,然后將得到的原始值轉(zhuǎn)換為字符串。此轉(zhuǎn)換在將對象傳遞給接受字符串參數(shù)的內(nèi)置函數(shù)時發(fā)生,例如使用String()
作為轉(zhuǎn)換函數(shù)或?qū)ο蟛迦氲侥0逦淖种袝r。
從對象到數(shù)字的轉(zhuǎn)換。?
當(dāng)需要將對象轉(zhuǎn)換為數(shù)字時,JavaScript首先使用數(shù)字提示算法將其轉(zhuǎn)換為原始值,然后將得到的原始值轉(zhuǎn)換為數(shù)字。接受數(shù)字參數(shù)的內(nèi)置JavaScript函數(shù)和方法執(zhí)行此轉(zhuǎn)換,當(dāng)操作數(shù)是對象時,JavaScript的大多數(shù)運(yùn)算符(除了下面指出的幾個例外)也會執(zhí)行此轉(zhuǎn)換。
運(yùn)算符轉(zhuǎn)換的特殊情況。?
在這里,我們只會討論不遵循上述基本對象到字符串或?qū)ο蟮綌?shù)字轉(zhuǎn)換規(guī)則的運(yùn)算符異常。
首先,JavaScript中的+
運(yùn)算符既執(zhí)行數(shù)字加法又執(zhí)行字符串連接。如果一個操作數(shù)是對象,JavaScript將使用默認(rèn)提示算法將對象轉(zhuǎn)換為原始值。如果兩個操作數(shù)都是原始值,則檢查它們的類型。如果至少有一個參數(shù)是字符串,則另一個原始值也會被轉(zhuǎn)換為字符串,然后將兩個字符串連接在一起。否則,兩個參數(shù)都會被轉(zhuǎn)換為數(shù)字,然后計算它們的和。
其次,==
和!=
運(yùn)算符執(zhí)行松散的等式測試,允許類型轉(zhuǎn)換。如果一個操作數(shù)是對象,另一個操作數(shù)是原始值,這些運(yùn)算符將使用默認(rèn)提示算法將對象轉(zhuǎn)換為原始值,然后比較兩個原始值。
最后,比較運(yùn)算符<=
、>
和>=
將操作數(shù)比較為數(shù)字或字符串。如果一個操作數(shù)是對象,則使用默認(rèn)提示算法將對象轉(zhuǎn)換為原始值,使用數(shù)字提示算法。然而,需要注意的是,與對象到數(shù)字的轉(zhuǎn)換不同,從這種對象到數(shù)字的轉(zhuǎn)換的結(jié)果原始值不會進(jìn)一步轉(zhuǎn)換為數(shù)字。
值得注意的是,雖然Date對象的數(shù)值表示可以通過<
和>
進(jìn)行有意義的比較,但其字符串表示則不能。JavaScript中的<=
、>
和>=
運(yùn)算符使用數(shù)字提示算法的事實(shí)意味著我們可以有意義地比較兩個Date對象的順序。
toString()
和valueOf()
方法。
所有對象都繼承了兩個在對象到原始值轉(zhuǎn)換中使用的方法。在解釋to-string、to-number和默認(rèn)轉(zhuǎn)換算法之前,我們必須首先介紹這兩個方法。
第一個方法是toString()
,其任務(wù)是返回對象的字符串表示。默認(rèn)情況下,toString()
方法不返回任何特定的內(nèi)容:
// => "[object Object]"
({x: 1, y: 2}).toString()
許多類定義了它們自己特定版本的toString()
方法。例如,Array類的toString()
方法將數(shù)組的每個元素轉(zhuǎn)換為字符串,并使用逗號作為分隔符連接它們。Function類的toString()
方法將用戶定義的函數(shù)轉(zhuǎn)換為包含函數(shù)的JavaScript源代碼的字符串。Date類的toString()
方法返回一個可讀(并可被JavaScript解析)的日期和時間字符串。RegExp類的toString()
方法將RegExp對象轉(zhuǎn)換為類似于RegExp字面量的字符串:
另一個轉(zhuǎn)換函數(shù)稱為valueOf()
。該方法的任務(wù)沒有明確定義,并且通常被認(rèn)為返回表示對象的原始值(如果存在這樣的值)。由于對象是復(fù)雜的值,大多數(shù)對象不能由單個原始值準(zhǔn)確表示,因此valueOf()
方法默認(rèn)情況下只返回對象本身,而不是原始值。String、Number和Boolean等封裝類的valueOf()
方法也只返回封裝的原始值。Array、Function和RegExp等類繼承默認(rèn)的valueOf()
方法,該方法返回對象本身。在這些類型的實(shí)例上調(diào)用valueOf()
方法將返回對象本身。Date類的valueOf()
方法返回自1970年1月1日以來的毫秒數(shù),表示日期的內(nèi)部表示:
對象到原始值轉(zhuǎn)換算法。
現(xiàn)在我們已經(jīng)介紹了toString()
和valueOf()
方法,我們可以粗略地解釋前面提到的三個對象到原始值轉(zhuǎn)換算法的實(shí)現(xiàn)。
· 字符串提示算法首先嘗試toString()
方法。如果此方法被定義并返回一個原始值,JavaScript將使用該值(即使它不是字符串)。如果toString()
不存在或存在但返回一個對象,JavaScript會嘗試valueOf()
方法。如果此方法存在并返回一個原始值,JavaScript將使用該值。否則,轉(zhuǎn)換失敗并拋出TypeError
。
· 數(shù)字提示算法類似于字符串提示算法,只是它首先嘗試valueOf()
方法,然后是toString()
方法。
· 默認(rèn)提示算法取決于要轉(zhuǎn)換的對象的類。如果是Date對象,JavaScript將使用字符串提示算法。對于其他對象類型,JavaScript將使用數(shù)字提示算法。
這些規(guī)則適用于所有內(nèi)置的JavaScript類型,并作為所有自定義類的默認(rèn)規(guī)則。
在結(jié)束類型轉(zhuǎn)換的討論之前,重要的是要注意,從原始值轉(zhuǎn)換規(guī)則的細(xì)節(jié)可以解釋為什么空數(shù)組會轉(zhuǎn)換為數(shù)字0,以及為什么只有一個元素的數(shù)組也可以轉(zhuǎn)換為數(shù)字:
從對象到數(shù)字的轉(zhuǎn)換首先使用數(shù)字提示算法將對象轉(zhuǎn)換為原始值,然后將得到的原始值轉(zhuǎn)換為數(shù)字。數(shù)字提示算法首先嘗試valueOf()
,如果不可用,則回退到toString()
。Array類繼承了默認(rèn)的valueOf()
方法,它不返回原始值。因此,當(dāng)將數(shù)組轉(zhuǎn)換為數(shù)字時,它最終調(diào)用toString()
(程序員的軟技能:ke.qq.com/course/6034346)