前端開發系列042-基礎篇之TypeScript語言特性(二)
title: '前端開發系列042-基礎篇之TypeScript語言特性(二)'
tags:
- javaScript系列
- TypeScript系列
categories: []
date: 2017-11-20 18:05:13
這篇文章中我們將繼續在語言特性方面展開探討,主要介紹了TypeScript中流程控制結構、類以及介面等方面的內容,需要說明的是這篇文章中並不會就相關特性的細節深入展開,你能得到的將只有對它們進行的淺嘗輒止介紹。
一、流程控制結構
我們知道世界上所有的程式都可以簡單劃分為順序、分支和迴圈
這三種結構,使用這三種基本結構組合能夠表示所有複雜的結構。順序結構就是按固定的順序來執行特定的程式碼(通常是自上而下執行),分支結構
初始條件、迴圈檢測條件、迴圈體以及退出機制
組成。TypeScript語言中的流程控制結構和JavaScript保持一致。
迴圈結構
TypeScript語言中的迴圈結構主要有:while迴圈
、do..while迴圈
、for..in迴圈
以及常用*for迴圈
,下面分別介紹並給出示例程式碼。
//檔案路徑 ../02-流程控制結構/01-迴圈結構.ts //[001] while迴圈結構 //說明:while語句用來在滿足判斷條件的情況下重複執行一段程式碼,程式碼在執行的時候會先檢查判斷條件是否滿足, //如果條件滿足則執行迴圈體(更新條件變數),否則就結束當前迴圈執行後面的程式碼,重複這個過程 let i:number = 0; while(i < 5) { i++; console.log(i); } //[002] do..while迴圈結構 //說明:do...while迴圈結構能夠保證迴圈體至少會被執行一次,當迴圈體執行完後,程式碼會檢查判斷條件是否滿足, //如果滿足條件則繼續執行迴圈體,否則就結束當前迴圈執行後面的程式碼,重複這個過程 let j:number = 5; do{ j--; console.log(j); }while(j>0); //[003] for迴圈 //說明:執行for迴圈的時候的執行順序為 //(1) 執行初始化語句,初始化變數n //(2) 檢查是否滿足迴圈條件 // A: 如果滿足迴圈條件,那麼就執行迴圈體,並跳轉到(3) // B: 如果不滿足迴圈條件,那麼就結束當前迴圈,繼續執行後面的任務 //(3) 更新迴圈變數,這裡為n++操作 //(4) 跳轉到(2) //關於break、continue和return //在迴圈體中,如果遇到break和return則表示結束迴圈(迴圈本身以及迴圈內後面的程式碼不再執行),執行迴圈後面的任務 //如果遇到continue則表示結束當前迴圈,繼續執行後面的迴圈任務 for(let n:number = 0 ; n < 5; n++) { if(n === 3) continue; console.log(n); } //[004] for..in迴圈 //說明:for..in迴圈主要用於遍歷程式碼中的物件 //注意:不推薦使用for..in迴圈來遍歷陣列或偽陣列物件,因為它會把原型成員迭代出來。 let obj:any = {name:"zs",age:18,"des":"描述資訊"}; for( let key in obj) { console.log("當前迴圈的key: "+key+" value:"+obj[key]); }
分支結構
TypeScript語言中的分鐘結構主要有if..else語句
和switch語句
,同JavaScript語言保持一致。下面還是貼出簡短的程式碼示例:
//檔案目錄 ../02-流程控制結構/02-分支結構.ts //分支結構其實就是林中路在某個節點分叉為多條,而只能選擇其中一條路繼續走下去 //具體走哪條路就像是人生抉擇,得出結選擇論的部分被稱為判斷條件,是布林型別的值(true/fasle) //[01] if條件語句結構 //當條件滿足的時候,執行{}中的程式碼,否則就忽略 let temp:boolean = true; if(temp) { console.log("temp的值為true") } //..... //[02] if...else語句結構 //給定兩條路,只能也必須走某一條 if(temp) { console.log("temp的值為true") }else{ console.log("temp的值為false") } //[03] if...else if...語句結構 //給定多條路,根據條件進行選擇其中的一條 let i:number = 85; if(i >= 90) { console.log("優秀") }else if(i >= 80){ console.log("良好") }else if(i >= 60) { console.log("及格") }else { console.log("不及格") } //輸出結果為:良好 //[04] switch結構 //switch語句接受一個表示式,會將表示式的值和case語句進行匹配,然後執行關聯的語句塊。 //為提高程式碼的可讀性,避免魔法數字等出現,常結合列舉型別組織程式碼結構 enum Animal{ Dog, Cat, Pig } let animalType:any = Animal.Dog; switch(animalType) { case Animal.Dog: console.log("Dog: 汪汪汪!!!"); break; case Animal.Cat: console.log("Cat: 喵喵喵!!!"); break; case Animal.Pig: console.log("Pig: 呵呵呵!!!"); break; default: console.log("其他動物..."); }
二、 類(Class)
我們知道JavaScript本身支援面向物件程式設計,但實現的方式和其它典型面向物件程式語言截然不同,JavaScript中沒有Class的概念,其多型、繼承等特性主要依靠函式和原型機制來實現,這種實現機制讓很多java/C++型開發者困惑不已。
從ES6開始,JavaScript將支援基於類的面向物件實現。 在TypeScript中,允許開發者現在就使用Class特性,並且編譯後的JavaScript可以在所有主流瀏覽器和平臺上執行,而不需要等到下個JavaScript版本。
下面給出TypeScript中類的典型結構:
//檔案路徑 ../03-Class的使用/01-Class的典型結構.ts
//類的定義
class Person{
age:number; //age屬性
name:string; //name屬性
constructor(name:string,age:number){ //呼叫時內部自動執行該程式碼段
this.age = age;
this.name = name;
console.log("執行內部的建構函式.");
}
getInfo(){ //getInfo方法
return "姓名:" + this.name + " 年齡:" + this.age
}
}
//使用new來構造Greeter類的例項物件
var p = new Person("wendingding",18);
console.log(p);
上面的程式碼中,我們定義了一個名為Person的類,這個類擁有四個成員為:name屬性、 age屬性、getInfo方法和constructor建構函式
。在Class的內部,我們可以通過 this來引用類中的成員。
當類被定義之後,我們可以使用 new來呼叫這個Class。 具體執行的時候,它會先呼叫Class中定義的建構函式執行初始化操作,並創建出一個當前類的例項物件返回。
下面貼出上面程式碼編譯為JavaScript程式碼後的結構:
var Person = /** @class */ (function () {
function Person(name, age) {
this.age = age;
this.name = name;
console.log("執行內部的建構函式.");
}
Person.prototype.getInfo = function () {
return "姓名:" + this.name + " 年齡:" + this.age;
};
return Person;
}());
//使用new來構造Greeter類的例項物件
var p = new Person("wendingding", 18);
console.log(p);
通過觀察可以發現,類其本質上是依靠閉包函式和原型物件來實現的
。
三、介面(interface)
TypeScript提供了介面機制。其實,TypeScript其核心原則之一就是能夠對值所具有的結構進行型別檢查
,這種處理方式被稱為“鴨式辨型法”。我們可以利用介面來為程式碼定義契約。
如果在設計某個函式的時候,我們希望該函式接受的引數物件(即函式的引數是一個物件)必須包含某個指定的屬性,且型別固定。假設函式名為logNameAndOtherInfo,傳遞給該函式的物件引數必須要擁有name這個屬性,且型別必須為string,我們可以嘗試給出如下程式碼
function logNameAndOtherInfo(obj:any){
console.log("name:"+obj.name);
console.log("Other:預設的其它資訊,這裡不做處理");
}
let obj1:any = {name:"文頂頂",age:18};
let obj2:any = {color:"red",age:18};
logNameAndOtherInfo(obj1); //name:文頂頂 //Other:預設的其它資訊,這裡不做處理
logNameAndOtherInfo(obj2); //undefined //Other:預設的其它資訊,這裡不做處理
觀察上面的程式碼,我們會發現logNameAndOtherInfo函式無力在展示函式引數物件內部屬性和型別方面有所作為。這種場景下,介面就可以派上用場。
//檔案路徑 ../03-Class的使用/03-介面簡單示例02.ts
interface ObjWithNameValue {
name: string;
}
function logNameAndOtherInfo(obj:ObjWithNameValue){
console.log("name:" + obj.name);
console.log("Other:預設的其它資訊,這裡不做處理");
}
let obj1:any = {name:234,age:18};
let obj2:any = {color:"red",age:18};
logNameAndOtherInfo(obj1); //name:文頂頂 //Other:預設的其它資訊,這裡不做處理
logNameAndOtherInfo(obj2); //undefined //Other:預設的其它資訊,這裡不做處理
除此之外,TypeScript中的介面與C#或Java裡的基本作用一樣,也能夠用它來明確的強制一個類去符合某種契約。
//檔案路徑 ../03-Class的使用/03-介面簡單示例03.ts
interface PersonInterface {
name: string;
getInfo();
}
//類的定義,需要遵循介面的約定
class Person implements PersonInterface{
//報錯:Property 'name' in type 'Person' is not assignable to the same property in base type 'PersonInterface'.
//name:number; 錯誤的演示(型別和介面不一致)
name:string;
constructor(name:string){ //呼叫時內部自動執行該程式碼段
this.name = name;
console.log("執行內部的建構函式.");
}
getInfo(){ //getInfo方法
return "姓名:" + this.name;
}
}
//使用new來構造Greeter類的例項物件
var p = new Person("wendingding.com");
程式碼說明:在上面的程式碼中,我們定義了一個名為PersonInterface的介面,和一個實現了該介面的Person類,它能夠確保實現了介面的類一定擁有指定的結構。
型別檢查器不會去檢查屬性的順序,只要相應的屬性存在並且型別匹配即可。備註:該文章所有的示例程式碼均可以點選在Github託管倉庫獲取