天天看點

《JavaScript面向對象程式設計指南》——2.3 基本資料類型

本節書摘來自異步社群《javascript面向對象程式設計指南》一書中的第2章,第2.3節,作者: 【加】stoyan stefanov 譯者: 淩傑 更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

我們在程式中所使用的任何值都是有類型的。在javascript中,主要包含以下幾大基本資料類型。

1.數字——包括浮點數與整數,例如1、100、3.14。

2.字元串——一序列由任意數量字元組成的序列,例如"a"、"one"、"one 2 three"。

3.布爾值——true或false。

4.undefined——當我們試圖通路一個不存在的變量時,就會得到一個特殊值: undefined。除此之外,使用一個未初始化的變量也會如此。因為javascript會自動将變量在初始化之前的值設定為undefined。

5.null——這是另一種隻包含一個值的特殊資料類型。所謂的null值,通常是指沒有值、空值,不代表任何東西。null與undefined最大的不同在于,被賦予null的變量通常被認為是已經定義了的,隻不過它不代表任何東西。關于這一點,我們稍後會通過一些具體的示例來解釋。

任何不屬于上述五種基本類型的值都會被認為是一個對象。甚至有時候我們也會将null視為對象,這會使人有些尴尬——這是一個不代表任何東西的對象(東西)。我們将會在第4章中深入闡述對象的概念,現在我們隻需要記住一點,javascript中的資料類型主要分為以下兩個部分。

基本類型(上面列出的五種類型)。

非基本類型(即對象)。

2.3.1 檢視類型操作符——typeof

如果我們想知道某個變量或值的資料類型,可以調用一種叫做typeof的特殊操作符。該操作符會傳回一個代表資料類型的字元串,它的值包括:“number”、“string”、“boolean”、“undefined”、“object”和“function”。在接下來的幾節中,我們将會逐一展示對五種基本資料類型使用typeof操作符時的情況。

2.3.2 數字

最簡單的數字類型當然就是整數了。如果我們将一個變量指派為1,并對其調用typeof操作符,控制台就會傳回字元串“number”,請看下面的代碼。此外要注意的是,當您第二次設定變量值時,就不需要再使用var語句了。

當然,這也同樣适用于浮點數(即含小數部分的數字):

1 除了對變量指派以外,我們也可以直接對一個數值調用typeof。例如:

2.3.2.1 八進制與十六進制

當一個數字以0開頭時,就表示這是一個八進制數。例如,八進制數0377所代表的就是十進制數255。

如您所見,例子中最後一行所輸出的就是該八進制數的十進制表示形式。如果您對八進制數還不太熟悉,那麼十六進制您一定不會感到陌生,畢竟,css樣式表中的顔色值使用的都是十六進制。

在css中,我們定義顔色的方式有以下兩種。

使用十進制數分别指定r(紅)、g(綠)、b(藍)的值2,取值範圍都為0~255。例如rgb(0,0,0)代表黑色、rgb(255,0,0)代表紅色(紅值達到最大值,而綠和藍都為0值)。

使用十六進制數,兩個數位代表一種色值,依次是r、g、b。例如#000000代表黑色、#ff0000代表紅色,因為十六進制的ff就等于255。

在javascript中,我們會用0x字首來表示一個十六進制值(簡稱為hex)。

2.3.2.2 指數表示法

一個數字可以表示成1e1(或者1e+1、1e1、1e+1)這樣的指數形式,意思是在數字1後面加1個0,也就是10。同理,2e+3的意思是在數字2後面加3個0,也就是2000。

此外,我們也可以将2e+3了解為将數字2的小數點向右移三位。依照同理,2e-3也就能被了解為是将數字2的小數點左移三位。

《JavaScript面向對象程式設計指南》——2.3 基本資料類型

2.3.2.3 infinity

在javascript中,還有一種叫做infinity的特殊值。它所代表的是超出了javascript處理範圍的數值。但infinity依然是一個數字,我們可以在控制台使用typeof來測試infinity。當我們輸入1e308時,一切正常,但一旦将後面的308改成309就出界了。經實踐證明,javascript所能處理的最大值是1.7976931348623157e+308,而最小值為5e-324。

另外,任何數除0也為infinity:

infinity表示的是最大數(或者比最大數還要大的數),那麼最小數該如何表示呢?答案是在infinity之前加一個負号:

但這是不是意味着我們可以得到雙倍的infinity呢?——畢竟我們可以從0加到infinity,也可以從0減到-infinity。好吧,這隻是個玩笑。事實上這是不可能的,因為即便将正負infinity相加,我們也不會得到0,而是會得到一個叫做nan(not a number的縮寫,即不是數字)的東西。

而且,infinity與其他的任何操作數執行任何算術運算的結果,都是infinity。

2.3.2.4 nan

還記得之前見過的那個nan嗎?盡管該值的名字叫做“不是數字”,但事實上它依然屬于數字,隻不過是一種特殊的數字罷了。

如果我們在對一個假定的數字執行某個操作時失敗了,就會得到一個nan。例如,當我們試圖将10與字元"f"相乘時,其結果就會為nan,因為"f"顯然是不支援乘法運算的。

而且,nan是具有傳染性的,隻要我們的算術運算中存在一個nan,整個運算就會失敗。

2.3.3 字元串

字元串通常指的是一組用于表示文本的字元序列。在javascript中,一對雙引号或單引号之間的任何值都會被視為一個字元串。也就是說,1是一個數字的話,"1"就是一個字元串了。在一個字元串上,typeof操作符會傳回“string”。

字元串中可以包含數字,例如:

如果引号之間沒有任何東西,它所表示的依然是一個字元串(即空字元串):

之前,當我們在兩個數字之間使用加号時,所執行的是加法運算。但在字元串中,這是一個字元串拼接操作,它傳回的是兩個字元串拼接之後的結果。例如:

像+這樣的雙功能操作符可能會帶來一些錯誤。是以,我們如果想執行拼接操作的話,最好確定其所有的操作數都是字元串。同樣的,在執行數字相加時,我們也要確定其所有的操作數都是數字。至于如何做到這一點,我們将會在後續章節中詳細讨論。

2.3.3.1 字元串轉換

當我們将一個數字字元串用于算術運算中的操作數時,該字元串會在運算中被當做數字類型來使用。(由于加法操作符的歧義性,這條規則不适用于加法運算。)

于是,将數字字元串轉換為數字就有了一種偷懶的方法:隻需将該字元串與1相乘即可。(當然,更好的選擇是調用parseint函數,關于這點,我們将會在下一章中介紹。)

如果轉換操作失敗了,我們就會得到一個nan值。

此外,将其他類型轉換為字元串也有一種偷懶的方法,隻需要将其與空字元串連接配接即可:

2.3.3.2 特殊字元串

在表2-2中,我們列出了一些具有特殊含義的字元串。

《JavaScript面向對象程式設計指南》——2.3 基本資料類型
《JavaScript面向對象程式設計指南》——2.3 基本資料類型

除此之外,還有一些很少被使用的特殊字元,例如:b(倒退符)、v(縱向制表符)、f(換頁符)等。

2.3.4 布爾值

布爾類型中隻有兩種值:true和false。它們可用于引号以外的任何地方。

如果true或false在引号内,它就是一個字元串。

2.3.4.1 邏輯運算符

在javascript中,主要有三種邏輯運算符,它們都屬于布爾運算。分别是:

!——邏輯非(取反)。

&&——邏輯與。

||——邏輯或。

在javascript中,如果我們想描述一些日常生活中非真即假的事物,就可以考慮使用邏輯非運算符:

如果在同一個值上執行兩次邏輯非運算,其結果就等于原值3:

如果在一個非布爾值上執行邏輯運算,該值會在計算期間被轉換為布爾值:

如您所見,上例中的字元串"one"是先被轉換為布爾值true然後再取反的,結果為false。如果我們對它取反兩次,結果就會為true。例如:

使用雙重取反操作可以很容易地将任何值轉換為等效的布爾值。雖然這種方法很少被用到,但從另一個角度也說明了将其他類型的值轉換為布爾值的重要性。而事實上,除了下面所列出特定值以外(它們将被轉換為false),其餘大部分值在轉換為布爾值時都為true。

空字元串""

null

undefined

數字0

數字nan

布爾值false

這6個值有時也會被我們統稱為falsy,而其他值則被稱為truthy(包括字元串"0"、""、"false")。

接下來,讓我們來看看另外兩個操作符——邏輯與和邏輯或的使用示例。當我們使用邏輯與操作符時,當且僅當該操作所有操作數為true時,它才為true。而邏輯或操作則隻需要至少一個操作數為true即可為true。

在表2-3中,我們列出了所有可能的情況及其相應結果。

《JavaScript面向對象程式設計指南》——2.3 基本資料類型

當然,我們也能連續執行若幹個邏輯操作。例如:

我們還可以在同一個表達式中混合使用&&和||。不過在這種情況下,我們最好用括号來明确一下操作順序。例如:

2.3.4.2 操作符優先級

您可能會想知道,為什麼上例中的第一個表達式(false && false || true && true)結果為true。答案在于操作符優先級。這看上去有點像數學,例如:

由于乘法運算的優先級高于加法,是以該表達式會先計算2<code>*</code> 3,這就相當于我們輸入的表達式是:

邏輯運算符也一樣,!的優先級最高,是以在沒有括号限定的情況下它将會被最先執行。然後,接下來的優先順序是先&amp;&amp;後||。也就是說:

與下面表達式等效:

最佳方法:

盡量使用括号,而不是依靠操作符優先級來設定代碼的執行順序,這樣我們的代碼才能有更好的可讀性。

2.3.4.3 惰性求值

如果在一個連續的邏輯操作中,操作結果在最後一個操作完成之前就已經明确了的話,那麼該操作往往就不必再繼續執行了,因為這已經不會對最終結果産生任何影響。例如,在下面這種情況中:

在這裡,所有的邏輯或運算符優先級都是相同的,隻要其中任何一個操作數為true,該表達式的結果就為true。因而當第一個操作數被求值之後,無論後面的值是什麼,結果都已經被确定了。于是我們可以允許javascript引擎偷個懶(好吧,這也是為了提高效率),在不影響最終結果的情況下省略一些不必要的求值操作。為此,我們可以在控制台中做個實驗:

除此之外,上面的例子還向我們顯示了另一個有趣的事情——如果javascript引擎在一個邏輯表達式中遇到一個非布爾類型的操作數,那麼該操作數的值就會成為該表達式所傳回的結果。例如:

通常情況下,這種行為是應該盡量避免的,因為它會使我們的代碼變得難以了解。但在某些時候這樣做也是有用的。例如,當我們不能确定某個變量是否已經被定義時,就可以像下面這樣,即如果變量mynumber已經被定義了,就保留其原有值,否則就将它初始化為10。

這種做法簡單而優雅,但是請注意,這也不是絕對安全的。如果這裡的mynumber之前被初始化為0(或者是那6個falsy值中的任何一個),這段代碼就不太可能如我們所願了。

2.3.4.4 比較運算符

在javascript中,還有另外一組以布爾值為傳回值類型的操作符,即比較操作符。下面讓我們通過表2-4來了解一下它們以及相關的示例。

《JavaScript面向對象程式設計指南》——2.3 基本資料類型
《JavaScript面向對象程式設計指南》——2.3 基本資料類型
《JavaScript面向對象程式設計指南》——2.3 基本資料類型

還有一件有趣的事情要提醒讀者注意:nan不等于任何東西,包括它自己。

2.3.5 undefined與null

通常情況下,當我們試圖通路某個不存在的或者未經指派的變量時,就會得到一個undefined值。javascript會自動将聲明時沒有進行初始化的變量設為undefined。

當我們試圖使用一個不存在的變量時,就會得到這樣的錯誤資訊:

這時候,如果我們在該變量上調用typeof操作符,就會得到字元串“undefined”:

如果我們聲明一個變量時沒有對其進行指派,調用該變量時并不會出錯,但typeof操作符依然會傳回“undefined”。

而null值就完全是另一回事了。它不能通過javascript來自動指派,隻能通過我們的代碼來完成。

盡管undefined和null之間的差别微乎其微,但有時候也很重要。例如,當我們對其分别執行某種算術運算時,結果就會截然不同:

這是因為null和undefined在被轉換為其他基本類型時,方法存在一定的差別,下面我們給出一些可能的轉換類型。

轉換成數字:

轉換成布爾值:

轉換成字元串:

繼續閱讀