揭祕Angular 2(一):TypeScript入門
3.1 TypeScript概述
3.1.1概述
3.1.2安裝
- 檢查
npm
是否已經安裝 -
接下來我們使用2.0正式版的
TypeScript
,安裝命令如下: -
寫第一個
Typescript
程式,並儲存到hello.ts
中,檔案中程式碼: -
通過
tsc
來編譯TypeScript
檔案:
3.2基本型別
- 布林型別(boolean)
- 數字型別(number)
- 字串型別(string)
- 陣列型別(array)
元祖型別(typule)
列舉型別(enum)
任意值型別(any)
- null和undefined
void型別
never型別
3.2.1 布林型別
3.2.2 數字型別
3.2.3 字串型別
let name:string=”Angular”;
let years:number=5;
let words:string=你好,今年是 ${name} 釋出 ${ years +1} 週年
3.2.4 陣列型別
3.2.5 元組型別
-
元祖型別用來表示已知元素數量和型別的陣列,各元素的型別不必相同
3.2.6 列舉型別
-
列舉是一個可被命名的整型常熟的集合,列舉型別為集合成員賦予有意義的名稱,增強可讀性
-
列舉預設下標是0,可以手動修改預設下標值:
3.2.7 任意值型別
-
任意值是
TypeScript
針對程式設計時型別不明確的變數使用的一種資料型別:-
變數的值會動態變化時
-
改寫現有程式碼時,任意值允許在編譯時可選擇地包含或移除型別檢查
-
定義儲存各種型別資料的陣列時:
-
3.2.8 null和undefined
-
在
TypeScript
中啟用嚴格的空校驗(--strictNullChecks)
特性,null
和undefined
只能被賦值給void
或本身對應的型別:
//啟用 –stricNullChecks
let x:number;
x=1; //執行正確
x=undefined; //執行錯誤
x=null; //執行錯誤-
上面例子中變數x只能是數字型別,如果可能出現null或者undefined,可以用
|
來支援多種型別
-
3.2.9 void型別
-
void
表示沒有任何型別-
函式沒有返回值時,返回值型別是
void
function hello():void{
alert(“Hello Angular”);
} -
對於可以忽略返回值的回撥函式來說,使用
void
型別比任意值型別更完全一些function func(foo:()=>void){
let f=foo();//使用函式foo的返回值
f.doSth();//報錯,void
型別不存在doSth()
方法,此時換成任意值型別則不報錯
}
-
3.2.10 never型別
-
never
是其它型別(包括null
和undefined
)的子型別,代表從不會出現的值
3.3宣告和解構
- 在TypeScript中,支援
var
、let
和const
這樣的宣告方式
3.3.1 let宣告
-
let
與var
宣告變數的寫法類似: -
let
宣告的變數只在塊級作用域內有效: -
塊級作用域不能在它宣告之前被讀取或賦值
-
let
不允許被重複宣告 -
let
宣告在下面兩種函式入參的對比:
3.3.2 const宣告
-
const
宣告與let
宣告相似,但const
宣告的是常量
,常量
不能被重新賦值,否則將編譯錯誤。但如果定義的常量
是物件
,物件
裡的屬性值
是可以被重新賦值的:
3.3.3 解構
-
解構就是將宣告的一組變數與相同結構的陣列或者物件的元素數值一一對應,並將變數相對應元素進行賦值。
-
陣列解構
-
也可作用於已宣告的變數:
-
或作用於函式引數:
-
在陣列解構中使用
rest
引數語法
-
-
物件解構
3.4 函式
3.4.1 函式定義
- 在
TypeScript
中支援函式宣告和函式表示式的寫法,示例程式碼如下:
//函式宣告寫法
//函式表示式寫法
3.4.2 可選引數
-
在
TypeScript
中,被調函式的每個引數都是必傳的 -
Typescript
提供了可選引數語法
3.4.3 預設引數
-
Typescript
還支援初始化預設引數,如果沒有給這個引數傳值或者傳的值為undefined
時,這個引數的值就是設定的預設值: -
如果預設值引數放到了必選引數的前面,使用者必須顯示地傳入
undefined
:
3.4.4 剩餘引數
-
當需要同時操作多個引數,或者並不知道會有多少引數傳遞進來時,就需要用到
Typescript
裡的剩餘引數
3.4.5 函式過載
-
函式過載通過為同一個函式提供多個函式型別定義來達到實現多種功能的目的。
3.4.6 箭頭函式
-
上面
giftPicker()
函式裡的this
被設定成了window
而不是gift
物件,因為這裡沒有對this
進行動態繫結,因此this
就指向了window
物件。 - 上面程式碼
TypeScript
提供的箭頭函式(=>
)很好地解決了這個問題,它在函式建立時就綁定了this
。
3.5 類
3.5.1 類的例子
-
傳統的
javascript
程式使用函式和基於原型繼承來建立可重用的”類”,這對於習慣了面向物件程式設計的開發者來說不是很友好。TypeScript
中可以支援使用基於類的面向物件程式設計。 -
看下面例子:
-
上面宣告一個汽車類
Car
,這個類有三個類成員:- 類屬性
engine
- 建構函式
drive()
方法
- 類屬性
-
其中類屬性
engine
,可通過this.engine
訪問 -
例項化一個
car
新物件,並執行建構函式初始化:
-
3.5.2 繼承與多型
封裝
、繼承
、多型
是面向物件的三大特性。- 上面的例子中把汽車的行為寫到一個類中,即所謂的封裝。
-
在
TypeScript
中,使用extends
關鍵字即可方便地實現繼承:MotoCar
和Jeep
是基類Car
的子類,通過extends
來繼承父類- 子類可以訪問父類的屬性和方法,也可以重寫父類的方法
Jeep
的drive()
方法重寫了Car
的drive()
方法,這樣的drive()
方法在不同的類中具有不同的功能,這就是多型
。- 即使
landRover
被宣告為Car
型別,它依然是子類Jeep
,landRover.drive(200)
呼叫的是Jeep
裡的重寫方法 - 派生類建構函式須呼叫
super()
,它會執行基類的構造方法
3.5.3 修飾符
-
類中的修飾符三種類型:
- 公共(public)
- 私有(private)
- 受保護(protected)
-
public修飾符
-
在
TypeScript
裡,每個成員預設為`public`,可以被自由地訪問:
-
-
private修飾符
-
當類成員被標記成
private
時,就不能在類的外部訪問它,示例程式碼如下: - ES6並沒有提供對私有屬性的語法支援,但是可以通過閉包來實現私有屬性
-
-
protected修飾符
- 注意,由於
engine
被宣告為protected
,所以不能在外部訪問它,但是仍然可以通過它的繼承類MotoCar
來訪問
- 注意,由於
3.5.4 引數屬性
-
引數屬性是通過給建構函式引數新增一個訪問限定符(
public
、protected
以及provate
)來宣告。- 在建構函式裡通過
protected engine:string
來建立和初始化engine
成員屬性,從而把宣告和賦值合併到一處。
- 在建構函式裡通過
3.5.5 靜態屬性
-
類的靜態成員存在於類本身而不是類的例項上
3.5.6抽象類
-
TypeScript
有抽象類的概念,它是供其它類繼承的基類,不能直接被例項化。抽象類必須包含一些抽象方法,同時也可以包含非抽象的成員。abstract
關鍵字用於定義抽象類和抽象方法。
3.6 模組
3.6.1 概述
- 模組在自身的作用域裡執行,而不是在全域性作用域裡,這意味著定義在一個模組裡的變數、函式和類等,在模組外是不可見的,除非明確地使用
export
匯出它們。反之,則必須通過import
匯入它們。 - 在
Angular
中,常見的模組載入器有SystenJS
和Webpack
3.6.2 模組匯出方式
-
匯出宣告
-
匯出語句(當我們需要對匯出的模組進行重新命名時,就用到了匯出語句)
-
模組包裝(修改和擴充套件已有的模組,並匯出供其他模組呼叫)
3.6.3 模組匯入方式
-
模組匯入與模組匯出相對應,可以使用
import
關鍵字來匯入當前模組依賴的外部模組。匯入有如下幾種方式:-
匯入模組
-
別名匯入
-
可以對整個模組進行別名匯入,將整個模組匯入到一個變數,並通過它來訪問模組的匯出部分:
-
-
3.6.4 模組的預設匯出
-
模組可以用
default
關鍵字實現預設匯出的功能,每個模組可以有一個預設匯出。-
預設匯出類
-
預設匯出函式
-
預設匯出值
-
3.6.4 模組設計原則
-
儘可能的在頂層匯出
-
返回多個物件的時候,可以採用頂層匯出的方式,呼叫的時候再明確地列出匯入的物件名稱即可:
-
明確的列出匯入的名字
-
在匯入的時候儘可能明確地指定匯入物件的名稱,這樣只要介面不變,呼叫方式就可以不變,從而降低了匯入跟匯出模板的耦合度,做到面向介面程式設計
-
-
使用名稱空間模式匯出
-
使用模組包裝進行擴充套件
-
我們可能經常要去擴充套件一個模組的功能,推薦的方案是不要去改變原來的物件,而是匯出一個新的物件來提供新的功能,示例程式碼如下:
-
-
3.7介面
3.7.1 概述
TypeScript
介面的使用方式類似於Java
3.7.2 屬性型別介面
-
在
TypeScript
中,使用interface
關鍵字來定義介面- 傳給
printLable()
方法的物件只要”形式上”滿足介面的需求即可 - 介面型別檢查器不會去檢查屬性順序,但要確保相應的屬性存在且型別匹配
- 傳給
-
TypeScript
還提供了可選屬性
3.7.3 函式型別介面
-
定義函式型別介面時,需要明確定義函式的
引數列表
和返回值型別
,且引數列表的每個引數都要有引數名
和型別
: -
如何使用函式型別介面: