「譯」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資料型別
- JavaScript隱式型別轉換趣解JavaScript型別
- 【關於Javascript】--- 隱式型別轉換篇JavaScript型別
- MySQL 隱式型別轉換MySql型別
- javascript中隱私型別轉換JavaScript型別
- C++隱式型別的轉換C++型別
- 資料型別的隱式轉換資料型別
- javascript資料型別隱式和顯式轉換詳解JavaScript資料型別
- javascript 隱式資料型別轉換程式碼例項JavaScript資料型別
- Java資料型別的顯式轉換和隱式轉換Java資料型別
- C語言的隱式型別轉換C語言型別
- javascript運算中的隱式型別轉換簡單介紹JavaScript型別
- C# 隱式型別轉換(轉載)C#型別
- 如何實現隱式型別轉換型別
- 談談 MySQL 隱式型別轉換MySql型別
- C++隱式類型別轉換C++型別
- C++ 隱式類型別轉換C++型別
- 索引失效系列——隱式型別轉換索引型別
- JavaScript 運算子規則與隱式型別轉換詳解JavaScript型別
- javascript 隱式轉換JavaScript
- JavaScript核心概念(1):型別轉換JavaScript型別
- c++隱式型別轉換存在的陷阱C++型別
- 建構函式定義的隱式型別轉換函式型別
- JavaScript 隱性型別轉換步驟淺析JavaScript型別
- 徹底理解c++的隱式型別轉換C++型別
- 資料型別隱式轉換導致的阻塞資料型別
- ORACLE中的隱式資料型別轉換(一)Oracle資料型別
- JavaScript 型別轉換JavaScript型別
- Oracle隱式型別轉換導致索引失效Oracle型別索引
- 33 個 JavaScript 核心概念系列(三): 顯式 (名義) 與 隱式 (鴨子)型別轉換JavaScript型別
- 從Java的型別轉換看MySQL和Oracle中的隱式轉換(二)Java型別MySqlOracle
- oracle資料型別隱式轉換----- 應急方案Oracle資料型別
- 欄位的資料型別隱式轉換有關係資料型別
- 說說JavaScript的型別轉換JavaScript型別
- 淺談JavaScript的型別轉換JavaScript型別