天天看點

TypeScript語言特性(上)1、類型2、變量、基本類型和運算符void

引言:typescript是一個開源的、跨平台且帶有類型系統的javascript超集,它可以編譯為純javascript,然後運作在任意的浏覽器和其他環境中。它使開發者可以使用一些未來javascript标準(ecmascript 6和7)中的特性。typescript為javascript添加了可選的靜态類型、類和子產品,讓大型javascript應用可以使用更好的工具并擁有更清晰的結構。

本文選自《learning typescript中文版》一書,本文将帶您了解類型、變量、基本類型和運算符的語言特性。

typescript 是 javascript 的超集。typescript 通過向 javascript 增加可選的靜态類型聲明來把javascript變成強類型的程式語言。可選的靜态類型聲明可限制函數、變量、屬性等程式實體,這樣編譯器和相應的開發工具就可以在開發過程中提供更好的正确性驗證和幫助功能(比如intellisense)。

強類型特性能讓程式員對自己和其他開發團隊人員在代碼中表達他的意圖。

typescript的類型檢測在編譯期進行并且沒有運作時開銷。

typescript非常擅長類型推導,但是在很多情況下沒有辦法自動偵測出一個對象或者變量的類型。在這些情況下,typescript允許我們明确地聲明一個變量的類型。這種允許聲明變量類型的功能就是被大家所熟知的可選的靜态類型聲明(optional static type notation)。對于變量來說,類型聲明在變量名後面并且前面有一個冒号:

可以看到,變量的類型聲明在變量名後面這種風格是基于類型理論,且更強調類型是可選的。當沒有類型聲明的時候,typescript會嘗試檢查指派給變量的值來推測變量的類型。舉例來說,在上面代碼片段的第二行裡,我們可以看到變量counter被識别出是number類型,因為它被指派為number類型的0。這種類型被自動推測出來的過程被稱為類型推導(type inference),當一個變量的類型無法被推測時,一個特殊的類型 any 會作為它的類型。

基本類型有boolean、number、string、array、void和所有使用者自定義的enum 類型。所有這些類型在typescript中,都是一個唯一的頂層的any type類型的子類型,any關鍵字代表這種類型。讓我們看一下這些原始類型。

與string和number資料類型在理論上可以有無數個值不同,boolean類型隻可能是兩種值。它們分别是true和false。一個 boolean 值是一個真實性的值,它代表條件是否正确。

和在javascript中一樣,所有的數字在typescript中都是浮點數。這些浮點數全部都是number類型。

在 typescript 中,string類型用來表示文本。在代碼中使用字元串是将它們放在引号或者雙引号中間。單引号中的字元串可以包含雙引号,雙引号中的字元串也可以包含單引号。

和 javascript 一樣, typescript 允許使用數組。array類型的聲明有兩種寫法。第一種,可以在數組元素的類型後面跟着[]來表示包含這種類型元素的數組:

第二種是使用範型數組類型array:

enum類型是為了給一個數字集合更友好地命名。enum類型中的成員預設從0開始,但你也可以手動設定成員中的值來更改這種預設行為。

any類型可以表示任意javascript值。一個any類型的值支援所有在javascript中對它的操作,并且對一個 any 類型的值操作時僅進行最小化靜态檢查。

使用any類型是與現存的javascript代碼一起工作的一種高效的方式,你可以在編譯期逐漸添加或者去除類型檢查。any類型在你隻知道一部分類型的情況下也很友善,比如你可能有一個混合了各種類型元素的數組:

在某種程度上,any的對立面就是void,即所有的類型都不存在的時候。你會在一個函數沒有傳回值時看到它:

javascript的原始類型也包括了undefined和null。在javascript中,undefined是全局作用域的一個屬性,它會指派給那些被聲明但未被初始化的變量。null是一個字面量(不是全局對象的一個屬性),它可以被指派給那些表示沒有值的變量。

在 typescript 中,我們不能把 null 或 undefined 當作類型使用:

因為 null 和 undefined 都不能被當作類型使用,是以上面這些代碼都是不合法的。

var、let和const

在 typescript 中,當聲明一個變量時,可以使用var、let和const關鍵字:

使用var聲明的變量儲存在最近的函數作用域中(如果不在任何函數中則在全局作用域中)。

使用let聲明的變量儲存在最近的比函數作用域小的塊作用域中(如果不在任何塊中則在全局作用域中)。

const關鍵字會建立一個儲存在建立位置作用域中的常量,可以是全局作用域也可以是塊作用域。

typescript 允許聲明聯合類型:

聯合類型用來聲明那些可以存儲多種類型值的變量。在上面這個例子中,我們聲明了一個可以存儲一個(字元串)或者一組路徑(字元串數組)的變量path。在例子中,我們也對這個變量進行了指派,将字元串和字元串的數組合法地指派給了這個變量。然而,當試圖将一個數字指派給它時我們遇到了一個編譯錯誤,因為這個聯合類型并沒有聲明 number為它的合法類型。

類型守護

可以在運作時使用typeof或者instanceof運算符對類型進行驗證。typescript語言服務會在if區域尋找這些運算符,然後對應地更改類型:

在這段代碼中,我們首先聲明了一個any類型的變量x,随後在運作時通過typeof運算符對x進行了類型檢查。如果x的類型為string時,我們就會嘗試調用被認為是x的一個成員的splice方法。typescript語言服務可以讀懂在條件語句中使用typeof的用法。typescript會自動推斷出x一定是string類型,然後告訴我們splice方法不存于string類型上。這種特性被稱為類型守護。

類型别名

typescript允許使用type關鍵字聲明類型别名:

類型别名實質上與原來的類型一樣,它們僅僅是一個替代的名字。類型别名可以讓代碼的可讀性更高,但是它也會導緻一些問題。

如果你在一個很大的團隊中工作,毫無限制地建立類型别名會導緻可維護性的問題。在maintainable javascript(由nicholas c. zaka所著)一書中,作者建議應避免修改一個不屬于你的對象。nicholas說的是,避免對那些不是你自己聲明的對象(dom對象、bom對象、原始類型和第三方庫)進行修改和覆寫,我們同樣能将其應用到别名的使用上。

環境聲明允許在typescript 代碼中建立一個不會被編譯到 javascript中的變量。這個特性是用來促進與現有 javascript 代碼、dom(文檔對象模型),還有bom(浏覽器對象模型)結合而設計的。讓我們看一個例子:

如果你嘗試調用customconsole對象上的log方法,typescript會告訴我們customconsole對象未被聲明:

出現這種情況并不令人意外。但是,有時候我們希望調用一個未被定義的對象上的方法,比如window對象上的console方法。

當通路 dom 或 bom 對象時,我們沒有遇到錯誤,是因為這些對象已經在一個特殊的 typescript 檔案(被稱為聲明檔案)中被聲明了。可以使用declare操作符建立一個環境聲明。

在下面這段代碼中,我們會聲明一個被customconsole對象實作的接口。然後使用declare操作符在作用域中增加一個customconsole對象:

然後就可以在沒有編譯錯誤的情況下使用customconsole:

typescript 預設包含一個名為lib.d.ts的檔案,它提供了像 dom 這種 javascript 内置庫的接口聲明。

使用.d.ts結尾的聲明檔案,是用來提高 typescript 對第三方庫和像 node.js 或浏覽器這種運作時環境的相容性的。

下表中列出的是typescript 支援的算術運算符。為了便于了解下面的例子,設定變量a的值總是10,變量b的值總是20。

TypeScript語言特性(上)1、類型2、變量、基本類型和運算符void

下面列出的是 typescript 支援的比較運算符。為了便于了解下面的例子,設定變量a的值總是10,變量b的值總是20。

運算符:==

描述:比較兩個運算元是否相等,如果相等則結果為 true

例子:(a == b)為 false,a == '10' 為 true

運算符:===

描述:比較兩個運算元的值和類型是否都相等,如果都相等則結果為 true

例子:(a === b)為 false,a === '10' 為 false

運算符:!=

描述:比較兩個運算元是否不等,如果不等則結果為 true

例子:(a != b) 為 true

運算符:!==

描述:比較兩個運算元的類型和值是否都不等,如果都不等則結果為 true

例子:(a !== '10') 為 true

運算符:>

描述:比較左邊的運算元是否大于右邊的運算元,如果大于則為 true

例子:(a > b) 為 false

運算符:<

描述:比較左邊的運算元是否小于右邊的運算元,如果小于則為 true

例子:(a < b) 為 true

運算符:>=

描述:比較左邊的運算元是否大于或等于右邊的運算元,如果大于或者等于則為true

例子:(a >= b) 為 false

運算符:<=

描述:比較左邊的運算元是否小于或等于右邊的運算元,如果小于或者等于則為true

例子:(a <= b) 為 false

下面列出的是typescript支援的邏輯運算符。為了便于了解下面的例子,設定變量a的值總是10,變量b的值總是20。

運算符:&&

描述:稱為邏輯與操作符,如果兩個運算元都為非零,則結果為 true

例子:(a && b)為true

運算符:|

描述:稱為邏輯或操作,如果兩個運算元任意一個為非零,則結果為true

例子:(a | | b)為true

運算符:!

描述:稱為邏輯非操作,用來對運算元取反。如果一個條件是true,那麼邏輯非操作會讓它變為 false

例子:!(a && b)為false

下面列出的是typescript支援的位運算符。為了便于了解下面的例子,設定變量a的值總是2,變量b的值總是3。

運算符:&

描述:稱為按位與操作符。對兩個運算元的每一個二進制位進行邏輯與操作

例子:(a & b) 為 2

描述:稱為按位或操作符。對兩個運算元的每一個二進制位進行邏輯或操作

例子:(a | b) 為3

運算符:^

描述:稱為按位異或操作符。對兩個運算元的每一個二進制位進行異或操作。異或操作的意思是兩個運算元不同時為 true,相同則為 false

例子:(a ^ b) 為 1

運算符:~

描述:稱為按位取反操作符。這是一個一進制操作符,它對操作元的每一個二進制位取反

例子:(~b) 為 -4

運算符:<<

描述:稱為左移位操作符。将第一個操作元的二進制形式向左移第二個操作元個比特位,右邊用0填充。移一位相當于乘以2,移兩位相當于乘以4,依此類推

例子:(a << 1) 為 4

運算符:>>

描述:稱為有符号右移位操作符。将第一個操作元的二進制形式向右移第二個操作元個比特位,左邊用符号位填充

例子:(a >> 1) 為 1

運算符:>>>

描述:稱為無符号右移操作符。與有符号右移位類似,除了左邊一律使用0 補位

例子:(a >>> 1) 為 1

讓我們像c++、java或者c#那樣使用移位操作的一個主要原因是它非常快。但是通常認為,位操作在typescript和javascript中并沒有那麼高效。位操作在 javascript 中效率不如其他語言的原因是,它必須先将操作元從浮點型(javascript 存儲數字的資料類型)轉換成32位整型進行運算,然後再轉換回浮點型。

下面列出的是typescript 支援的指派操作符。

運算符: 描述 例子

運算符:=

描述:這是最簡單的等于操作符,将右邊操作元的值賦給左邊的操作元

例子:c = a + b 會将 a + b 的結果指派給 c

運算符:+=

描述:這是加等于操作符,它将右邊的操作元與左邊的操作元相加後指派給左邊的操作元

例子:c += a 等價于 c = a + c

運算符:- =

描述:這是減等于操作符,它将左邊的操作元減去右邊的操作元再指派給左邊的操作元

例子:c - = a 等價于 c = c - a

運算符:*=

描述:這是乘等于操作符,它将右邊的操作元乘以左邊的操作元後指派給左邊的操作元

例子:c = a 等價于 c = c a

運算符:/=

描述:這是除等于操作符,它将左邊的操作元除以右邊的操作元後指派給左邊的操作元

例子:c /= a 等價于 c = c / a

運算符:%=

描述:這是餘等于操作符,它将兩個操作元取餘後指派給左邊的操作元

例子:c %= a 等價于 c = c % a

想及時獲得更多精彩文章,可在微信中搜尋“博文視點”或者掃描下方二維碼并關注。

TypeScript語言特性(上)1、類型2、變量、基本類型和運算符void

繼續閱讀