「譯」JavaScript 的怪癖 1:隱式型別轉換
原文:JavaScript quirk 1: implicit conversion of values
譯者: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型別
- JavaScript 隱式資料型別轉換JavaScript資料型別
- 【關於Javascript】--- 隱式型別轉換篇JavaScript型別
- javascript中隱私型別轉換JavaScript型別
- Java資料型別的顯式轉換和隱式轉換Java資料型別
- C語言的隱式型別轉換C語言型別
- javascript 隱式轉換JavaScript
- 如何實現隱式型別轉換型別
- JavaScript核心概念(1):型別轉換JavaScript型別
- c++隱式型別轉換存在的陷阱C++型別
- JavaScript 隱性型別轉換步驟淺析JavaScript型別
- 建構函式定義的隱式型別轉換函式型別
- 資料型別隱式轉換導致的阻塞資料型別
- 徹底理解c++的隱式型別轉換C++型別
- 說說JavaScript的型別轉換JavaScript型別
- 淺談JavaScript的型別轉換JavaScript型別
- 33 個 JavaScript 核心概念系列(三): 顯式 (名義) 與 隱式 (鴨子)型別轉換JavaScript型別
- [譯]隱式轉型,你值得掌握
- JavaScript 資料型別轉換JavaScript資料型別
- javascript資料型別轉換JavaScript資料型別
- golang 快速入門 [8.4]-常量與隱式型別轉換Golang型別
- [譯] [1] + [2] - [3] === 9!? 型別轉換深入研究型別
- 瞭解JavaScript中的型別轉換JavaScript型別
- '2'>'10'==true? JS是如何進行隱式型別轉換的?JS型別
- 從兩個小例子看js中的隱式型別轉換JS型別
- 沿著平滑的曲線學會 JavaScript 中的隱式強制型別轉換(基礎篇)JavaScript型別
- (譯)js中的神奇的型別轉換JS型別
- 前端面試官必問系列之隱式型別轉換前端面試型別
- JavaScript 字串轉換數值型別JavaScript字串型別
- JavaScript 基本資料型別轉換JavaScript資料型別
- 神奇的JavaScript弱等價型別轉換JavaScript型別
- 沿著平滑的曲線學會 JavaScript 中的隱式強制型別轉換(實戰應用篇)JavaScript型別
- SQL Server資料庫中的資料型別隱式轉換問題SQLServer資料庫資料型別
- Javascript基礎:變數型別轉換JavaScript變數型別
- JavaScript資料型別轉換總結JavaScript資料型別
- JavaScript資料型別分析及其轉換JavaScript資料型別
- js顯式轉換和隱式轉換JS
- JavaScript強制型別轉換的背後操作JavaScript型別
- PostgreSQL 原始碼解讀(210)- 隱式型別轉換(func_match_argtypes)SQL原始碼型別