一:Typescript簡介
維基百科: TypeScript是一種由微軟開發(fā)的自由和開源的編程語言。它是JavaScript的一個嚴格超集褐隆,并添加了可選的靜態(tài)類型和基于類的面向?qū)ο缶幊汤场#的首席架構(gòu)師以及Delphi和Turbo Pascal的創(chuàng)始人安德斯?海爾斯伯格參與了TypeScript的開發(fā)员舵。Typescript是ES6的超集工扎。添加了可選的靜態(tài)類型(注意并不是強類型)和基于類的面向?qū)ο缶幊汤峤础#ㄈ绻麑S6熟悉那么可以只關(guān)注類钓觉、裝飾器部分的內(nèi)容茴肥。)
中文官網(wǎng):https://www.tslang.cn/。
特點:微軟開發(fā)荡灾,javascript超集瓤狐,遵循ES6標(biāo)準(zhǔn),任何js語法都可以直接在ts里編寫運行卧晓。Angular2框架是用Typescript開發(fā)的芬首,背景是谷歌和微軟,有可能是未來的前端腳本語言發(fā)展的主流方向逼裆。優(yōu)點:支持ES6規(guī)范郁稍,學(xué)到的typescript語法未來是客戶端腳本語言的主流語法。強大的IDE支持: 1胜宇、類型檢查耀怜。 2、語法提示桐愉。 3财破、重構(gòu)(修改方法名稱的時候會自動把引用的地方都重構(gòu))是Angular2的首選開發(fā)語言。
二:環(huán)境搭建
主要是安裝Typescript的代碼編譯器从诲。
本地環(huán)境:一左痢、安裝好nodeJS環(huán)境。二系洛、npm install -g typescript俊性。三、tsc --version描扯。
三:Typescript特性
1. 字符串特性
1.1多行字符串
使用``包裹跨行的字符串定页,示例:
var html = `<div>
<span></span>
</div>`
1.2:字符串模板
可以在多行字符串中使用模板,示例:
var names = 'daocheng';
function getImg() {
return '<i></i>'
}
var html = `<div>${names}
<span>${getImg()}</span>
<div>
`
1.3:自動拆分字符串
function getData(template, name, age) {
console.log(template);
console.log(name);
console.log(age);
}
var names = 'daocheng';
var age = 23;
getData`你好绽诚,我的名字是${names}典徊,我今年${age}歲了`
2. 參數(shù)新特征
2.1:參數(shù)類型
Typescript中的參數(shù)類型包括:boolean/number/string/array/tuple/enum/any/(null和undefined)/ void /never杭煎。其中元祖(tuple)、枚舉卒落、任意值羡铲、void類型和never是有別于Javascript的特有類型。
2.2:類型聲明與默認參數(shù)
在Typescritpt中聲明變量儡毕,需要加上類型聲明犀勒,如boolean或string等。通過靜態(tài)類型約束妥曲,在編譯時執(zhí)行類型檢查贾费,這樣可以避免一些類型混用的低級錯誤。示例:
var names = 'daocheng';
function getData(name: stirng, age: number): boolean {
return true
}
Typescript還支持初始化默認參數(shù)檐盟。如果函數(shù)的某個參數(shù)設(shè)置了默認值褂萧,當(dāng)該函數(shù)被調(diào)用時,如果沒有給這個參數(shù)傳值或者傳值為undefined時葵萎,這個參數(shù)的值就是設(shè)置的默認值导犹。示例:
function max(x: number, y: number = 4): number {
return x > y ? x : y;
}
let result1 = max(2); //正常
let result2 = max(2, undefined); //正常
let result3 = max(2, 4, 7); //報錯
let result4 = max(2, 7); //正常
2.3: 可選參數(shù)
在javascript里,被調(diào)用函數(shù)的每個函數(shù)都是可選的羡忘,而在typescript中谎痢,被調(diào)用的每個函數(shù)的每個參數(shù)都是必傳的。在編譯時卷雕,會檢查函數(shù)每個參數(shù)是否傳值节猿。簡而言之,傳遞給一個函數(shù)的參數(shù)個數(shù)必須和函數(shù)定義的參數(shù)個數(shù)一致漫雕。但是實際開發(fā)中經(jīng)常需要根據(jù)實際需求來確認參數(shù)滨嘱,這時可以添加?來定義可選參數(shù)浸间。示例:
function max(x: number, y: number) {
if(y){
return x > y ? x : y;
} else {
return x
}
}
let result1 = max(2);
let result2 = max(2, 4, 7); //報錯
let result3 = max(2, 4);
//注意:可選參數(shù)必須放在默認參數(shù)后面
3:函數(shù)特性
3.1:剩余參數(shù)
上面介紹的必選參數(shù)太雨、默認參數(shù)以及可選參數(shù)共同點是只能表示某一個參數(shù)。當(dāng)需要同時操作多個參數(shù)魁蒜,或者并不知道會有多少參數(shù)傳遞進來時囊扳,就需要用到Typescript 里的剩余參數(shù)。示例:
function sum(x: number, ...restOfNumber: number[]){
let result = x;
restOfNumber.forEach(value => result += value);
return result;
}
let result1 = sum(1, 2, 3, 4, 5, 6);
console.log(result1);
let result2 = sum(2);
console.log(result2);
let result3 = sum(2, 5);
console.log(result3);
3.2: generator函數(shù)
控制函數(shù)的執(zhí)行過程兜看,可以手動的干預(yù)函數(shù)執(zhí)行锥咸。示例:
function getPrice(stock) {
while (1) {
yield Math.random() * 100;
}
}
var priceGenerator = getPrice('dcc');
var limitPrice = 51;
var price = 100;
while (price > limitPrice) {
price = priceGenerator.next().value;
console.log(`this generator return ${price}`);
}
console.log(`buying at ${price}`);
3.3: 析構(gòu)表達式
析構(gòu)表達式又稱解構(gòu),是ES6的一個重要特性铣减,Typescript在1.5版本中開始增加了對結(jié)構(gòu)的支持她君,所謂結(jié)構(gòu)脚作,就是將聲明的一組變量與相同結(jié)構(gòu)的數(shù)組或者對象的元素數(shù)值一一對應(yīng)葫哗。分數(shù)組解構(gòu)([])和對象解構(gòu)({})兩種缔刹。
數(shù)組解構(gòu)示例:
let imput = [1, 2];
let [first, second] = input;
console.log(first); //相當(dāng)于inputp[0]
console.log(second); //相當(dāng)于input[1]
function f([first, second]) {
console.log(first + second)
}
f{[1, 3]} //結(jié)果是4
let [first, ...rest] = [1, 2, 3, 4];
console.log(first); //1
console.log(second); //[2,3,4]
對象解構(gòu)示例:
let test = {
x: 0,
y: 0,
width: 15,
heights: {
height1: 10,
height2: 20
}
};
let { x, y: myY, width, heights: {height2} } = test;
console.log(x, myY, width, height2); //輸出:0,10,15,20
4: 箭頭表達式
用來聲明匿名函數(shù),消除傳統(tǒng)匿名函數(shù)的this指針問題劣针。示例:
function Test1(names: string) {
this.names = names;
setInterval(function() {
console.log('my name is ' + this.names);
}, 1000)
}
function Test2(names: string) {
this.names = names;
setInterval(() => {
console.log('my names is ' + this.names)
}, 1000)
}
var a = new Test1('daocheng'); //undefined
var b = new Test2('daocheng'); //daocheng
5: 循環(huán)
typescritpt中涉及三種高級循環(huán)方式:forEach()校镐、for in、for of
forEach示例:
var myArray = [1, 2, 3, 4];
myArray.name = 'daocheng';
myArray.forEach(value => console.log(value)); //結(jié)果為1,2,3,4
//特點:不支持break捺典,會忽略(name)
for in 示例:
var myArray = [1, 2, 3, 4];
myArray.name = 'daocheng';
for (var n in myArray ) {
console.log(n)
} //結(jié)果為1,2,3,4
//特點: 循環(huán)的結(jié)果是對象或者數(shù)組的鍵值鸟廓。可以break
for of 示例:
var myArray = [1, 2, 3, 4];
myArray.name = 'daocheng';
for (var n of myArray) {
console.log(n)
} //結(jié)果是1,2,3,4
//特點:忽略屬性襟己,可以打斷引谜。當(dāng)循環(huán)為字符串時,會把字符串中每個字符打出來
6:類
傳統(tǒng)的JavaScript程序使用函數(shù)和基于原型(Prototype)繼承來創(chuàng)建可重用的“類”擎浴,這對于習(xí)慣了面向?qū)ο缶幊痰拈_發(fā)者來說不是很友好员咽,Typescript中可以支持基于類(class)的面向?qū)ο缶幊?/p>
6.1: 類的聲明
class Car {
engine: string,
constructor(engine: string) {
this.engine = engine;
}
drive(distanceInMeters: number = 0) {
console.log(`aaa is running` + this.engine)
}
}
let car = new Car('petrol');
car.drive(100)
6.2: 類的封裝、繼承贮预、多態(tài)
封裝贝室、繼承、多態(tài)是面向?qū)ο蟮娜筇匦苑峦獭I厦娴睦影哑嚨男袨閷懙揭粋€類中滑频,即所謂的封裝。在Typescript中唤冈,使用extends關(guān)鍵字可以方便的實現(xiàn).
繼承峡迷。示例:
class Car {
engine: string;
constructor(engine: string) {
this.engine = engine;
}
drive(distanceInMeter: number = 0){
console.log(`A car runs ${distanceInMeter}m
powered by` + this.engine)
}
}
class MotoCar extends Car {
constructor(engine: string) {
super(engine)
}
}
let tesla = new MotoCar('electricity');
tesla.drive();
//其中子類MotoCar的實例對象tesla調(diào)用了父類Car的drive()方法。
多態(tài)示例:
class Car {
engine: string;
constructor(engine: string) {
this.engine = engine;
}
drive(distanceInMeter: number = 0){
console.log(`A car runs ${distanceInMeter}m
powered by` + this.engine)
}
}
class Jeep extends Car {
constructor(engine: string) {
super(engine)
}
drive(distanceInMeters: number = 100) {
console.log('jeep...')
return super.drive(distanceInMeters);
}
}
let landRover: Car = new Jeep('petrol'); //實現(xiàn)多態(tài)
> Jeep子類中的drive()方法重寫了Car的drive()方法你虹,這樣drive()方法在不同的類中就具有不同的功能凉当,這就是多態(tài)。注意:子類和派生類的構(gòu)造函數(shù)中必須調(diào)用super()售葡,它會實現(xiàn)父類構(gòu)造方法看杭。
6.3: 修飾符
在類中的修飾符可以分為公共(public)、私有(private)挟伙、和受保護(protected)三種類型楼雹。在Typescript里,每個成員默認為public尖阔,可以被自由的訪問贮缅。
私有修飾符示例:
class Car {
private engine: string;
constructor(engine: string) {
this.engine = engine;
}
}
new Car('petrol').engine; //報錯,私有屬性無法在類的外部訪問
受保護修飾符示例:
class Car {
engine: string;
constructor(engine: string) {
this.engine = engine;
}
protected drive() {
console.log('drving')
}
}
class MotoCar extends Car {
constructor(engine: string) {
super(engine)
}
moToDrive() {
super.drive()
}
}
let tesla = new MoToCar('electricity');
tesla.drive(); // 報錯介却,受保護成員只有子類訪問谴供,實例對象不可
tesla,moToDrive()
6.4: 參數(shù)屬性
參數(shù)屬性是通過給構(gòu)造函數(shù)的參數(shù)添加一個訪問限定符來聲明。參數(shù)屬性可以方便地讓我們在一個地方定義并初始化類成員齿坷。我們來改造6.1中的例子:
class Car {
constructor(public engine: string) {}
drive() { }
}
6.5: 抽象類
Typescript有抽象類的概念桂肌,它是供其他類繼承的基類数焊,不能直接被實例化。不同于接口崎场,抽象類必須包含一些抽象方法佩耳,同時也可以包含非抽象的成員。抽象類中的抽象方法必須在派生類中實現(xiàn)谭跨。
abstract class Person {
abstract speak(): void;
walking(): void {
console.log('walking');
}
}
class Male extends Person {
speak(): void {
console.log('man wakling')
}
}
6.6: 接口
接口在面向?qū)ο笤O(shè)計中具有極其重要的作用干厚,在Gof的23種設(shè)計模式中,基本上都可見到接口的身影螃宙。長期以來蛮瞄,接口模式一直是Javascript這類弱類型語言的軟肋,Typescript接口的使用方式類似于Java谆扎。
在Typescript中接口有屬性類型裕坊、函數(shù)類型、可索引類型燕酷、類類型這幾種籍凝,在Angular的開發(fā)中主要使用類類型接口,我們使用interface關(guān)鍵字定義接口并用implements關(guān)鍵字實現(xiàn)接口苗缩。
類類型接口示例:
interfance Animal {
name: string;
setName();
}
class Dog implements Animal {
name: string;
setName() {
console.log(this.name)
}
constructor() { }
}
//接口更注重功能的設(shè)計饵蒂,抽象類更注重結(jié)構(gòu)內(nèi)容的體現(xiàn)
6.7: 模塊
ES6中引入了模塊的概念,在TypeScript中也支持模塊的使用酱讶。使用import和export關(guān)鍵字來建立兩個模塊之間的聯(lián)系退盯。懂點node都知道模塊是什么了,不BB了泻肯。
7:裝飾器
裝飾器(Decorators)是一種特殊類型的聲明渊迁,它可以被附加到類聲明、方法灶挟、屬性或參數(shù)上琉朽。裝飾器有@符號緊接一個函數(shù)名稱,如:@expression稚铣,expression求職后必須是一個函數(shù)箱叁,在函數(shù)執(zhí)行的時候裝飾器的聲明方法會被執(zhí)行。裝飾器是用來給附著的主題進行裝飾惕医,添加額外的行為耕漱。(裝飾器屬于ES7規(guī)范)
在Typescript的源碼中,官方提供了方法裝飾器抬伺、類裝飾器螟够、參數(shù)裝飾器、屬性裝飾器等幾種每種裝飾器類型傳入的參數(shù)大不相同峡钓。這里我演示兩種裝飾器妓笙。
復(fù)合使用的例子:
function Component(component) {
console.log('selector: ' + component.selector);
console.log('template: ' + component.template);
console.log('component init');
return (target: any) => {
console.log('component call');
return target;
}
}
function Directive() {
console.log('directive init');
return (target: any) => {
console.log('directive call');
return target;
}
}
@Component({
selector: 'person',
template: 'person.html'
})
@Directive()
export class Person {}
let p = new Person();
//看不懂沒關(guān)系若河,知道有這么個東西就可以了,Angular框架在依賴注入给郊、組件等部分中有多個復(fù)合裝飾器應(yīng)用的場景.畢竟裝飾器是ES7的草案標(biāo)準(zhǔn)。
8:泛型
參數(shù)化的類型捧灰,一般用來限制集合的內(nèi)容淆九。
示例:
class MinHeap<T> {
list: T[] = [];
add(element: T): void {
//這里進行大小比較,并將最小值放在數(shù)組頭部毛俏,功能代碼省略炭庙。
}
min(): T {
return this.list.length ? this.list[0] : null
}
}
let heap = new MinHeap<number>();
heap.add(3);
heap.add(5);
console.log(heap.min())
9:聲明文件
聲明文件也稱為類型定義文件,當(dāng)我們項目中要使用第三方的Javascript庫如jQuery煌寇、lodash等就需要用聲明文件焕蹄,聲明文件是以.d.ts為后綴的形式存在的,其作用是描述一個Javascript模塊文件所有導(dǎo)出的接口類型信息阀溶。
例如使用jquery:
npm install –save @types/jquery