原文:JavaScript quirk 1: implicit conversion of values
譯文:「譯」JavaScript 的怪癖 1:隱式類型轉換
譯者:justjavac
零:提要
[此貼子是 javascript 的 12 個怪癖(quirks) 系列的第一篇。]
JavaScript 是非常寬容的,「來者不拒」,不在乎什麼類型。
例如,它如果想要接受數字,它並不拒絕其他類型的值,而是試圖把它們轉換成數字:
> '5' - '2'3> '5' * '2'10
自動轉換為布爾值通常不會引起問題,而且往往很有用(譯註:比如在C語言裡,根本就沒有布爾類型。by @justjavac)。 即使如此,這些隱式轉換也會引起怪癖(quirks)。 但是當自動轉換為字串時,可能會引起問題。
一:隱式轉換為布爾:“truthy”和“falsy”
當 JavaScript 需要一個布爾值時(例如:if
語句),任何值都可以被使用。
最終這些值將被轉換為 true
或 false
。
下面的值被轉換為 false
:
- undefined, null
- Boolean: false
- Number: -0, +0, NaN
- String: ''
所有其他值都認為是 true
。 被轉換成 'false' 的值我們成之為 falsy,被轉換成
'true' 的值我們成之為 truthy。 您可以使用 Boolean 來測試一個值到底被轉換成了什麼。
Boolean 將其參數轉換為布爾值(boolean):
> Boolean(undefined)false> Boolean(0)false> Boolean(3)true
二、字串的隱式轉換
在 Web 開發中,我們經常得到字串值,實際上我們期望的卻是數字或者布爾值。 例如,使用者輸入的表單中的資料。 如果你忘了對這些字串進行顯式的轉換,那麼 JavaScript 會令你感到驚訝,主要體現在兩個方面:
- 首先,系統不會有任何警告。
- 其次,這些值將被自動轉換,但確實錯誤的。
例如,加運算子(+),就有這方面的問題,因為**只要其中一個運算元是字串,那麼它就執行連接字串的操作(而不是加法操作,即使它們是數字)**。
在下面的 JavaScript 代碼中,我們本來預期是把 1 和 5 相加。 但是,我們使用了字串 '5' 和 '1' 。
> var x = '5'; // 錯誤的假設:x 是一個數字> x + 1'51'
此外,還有一些看似是 false
的值,如果轉換成字串,卻成了 'true'。
例如:false
。
> Boolean(false)false> String(false)'false'> Boolean('false') // !!true
例如: undefined
.
> Boolean(undefined)false> String(undefined)'undefined'> Boolean('undefined') // !!true
三、對象的隱式轉換
只有在 JavaScript 運算式或語句中需要用到數字或字串時,對象才被隱式轉換。 當需要將對象轉換成數字時,需要以下三個步驟:
- 調用
valueOf()
。如果結果是原始值(不是一個對象),則將其轉換為一個數字。
- 否則,調用
toString()
方法。如果結果是原始值,則將其轉換為一個數字。
- 否則,拋出一個類型錯誤。
第一步樣本:
> 3 * { valueOf: function () { return 5 } }15
第三步樣本:
> function returnObject() { return {} }> 3 * { valueOf: returnObject, toString: returnObject }TypeError: Cannot convert object to primitive value
如果把對象轉換成字串時,則轉換操作的第一步和第二步的順序會調換: 先嘗試 toString()
進行轉換,如果不是原始值,則再嘗試使用 valueOf()
。
四、相關閱讀
- JavaScript中,{}+{}等於多少?
- JavaScript:將所有值都轉換成對象
- 為什麼 ++[[]][+[]]+[+[]] =
10?