当前位置:网站首页>Web學習之TypeScript

Web學習之TypeScript

2022-06-26 00:46:00 on the moon

一. TypeScript是什麼

  • TypeScript是JavaScript類型的超集,擴展了 JavaScript 的語法;
  • TypeScript 設計目標是開發大型應用,它能編譯出純淨、簡潔的JavaScript代碼,可以運行在在任何瀏覽器、任何計算機和任何操作系統上,並且是開源的;
  • TypeScript 通過類型注解提供編譯時的靜態類型檢查,就能將調試從運行期提前到編碼期,諸如類型檢查、越界檢查這樣的功能才能真正發揮作用;
  • TypeScript的開發體驗遠遠超過以往純JavaScript的開發體驗,無需運行程序即可修複潜在bug;
  • TypeScript支持未來的ES6甚至ES7。在TypeScript中,可以直接使用ES6的最新特性,在編譯時它會自動編譯到ES5。

在這裏插入圖片描述

二. TypeScript配置

  1. 安裝好NodeJS後,以管理員身份運行終端,使用npm -g install ts-node typescript命令進行全局安裝;
  2. 在VS Code中開發,安裝TSLint、TypeScript Hero、Bracket Pair Colorizer等插件;
  3. 新建一個.ts後綴的文件,任意寫一段JS代碼,點擊運行試試是否配置成功。

三. 變量聲明

使用letconst新的聲明方式來代替var,並加上類型說明,且作用域為塊級即以{}為界。
const是對let的一個增强,它能阻止對一個變量再次賦值。

例如:

let lang: string = 'TypeScript';//如果省略類型說明,TS也可進行自動推斷
lang = 1010;//error! 如果需要可以使用聯合類型:let lang: number | string = 'TS';
let age: number = 89;
let age = 64;//error!

const pi: number = 3.14159;//pi以後不可改變,類似常量
pi = 3.14;//error!

四. 解構

將對象、數組中的元素拆分到指定變量中,以方便使用

//解構數組
let input = [89, 64, 2018, 10];
let [first, second] = input;//注意使用[]
console.log(first); // 89
console.log(second); // 64
let [one, ...others] = input; //...other錶示將剩餘的數組展開
console.log(...others);  //64 2018 10
let newArr = [89, ...others, 18];
console.log(newArr);  // [ 89, 64, 2018, 10, 18 ]

//解構對象
let o = {
    
  a: "foo",
  b: 12,
  c: "bar"
};
let {
    a, b} = o;//注意使用{},且變量名需與對象中道屬性名一致
console.log(a, b);  //foo 12

五. 函數

TypeScript為JavaScript函數添加了額外的功能,讓我們可以更容易地使用。

1. 使用完整函數類型定義

變量名:類型
function 函數名():返回值類型{}

//命名函數,有完整的參數和返回類型。可以不用,TS將自動進行類型推斷但推薦使用!
function add(x: number, y: number): number {
    
  return x + y;
}
//匿名函數
let myAdd = function(x: number, y: number): number {
     return x + y; };
console.log(myAdd(1, '2'));//error
console.log(myAdd(1));//error
console.log(typeof myAdd(1, 2));//number 

2. 可選參數

JavaScript裏,每個參數都是可選的,可傳可不傳;沒傳參的時候,它的值就是undefined。
在TypeScript裏使用變量名?:類型實現可選參數的功能。

例如,我們想讓last name是可選的:

function buildName(firstName: string, lastName?: string) {
    
    if (lastName)
        return firstName + " " + lastName;
    else
        return firstName;
}
console.log(buildName("Bob"));  // works correctly now
console.log(buildName("Bob", "Adams", "Sr."));  // error, too many parameters
console.log(buildName("Bob", "Adams"));  // right

注意:可選參數必須放在必要參數後面!!


3. 默認參數

在TypeScript裏,我們也可以為參數提供一個默認值,當用戶沒有傳遞這個參數或傳遞的值是undefined時,它們叫做有默認初始化值的參數。

修改上例,把last name的默認值設置為"Smith":

function buildName(firstName: string, lastName = "Smith") {
    
    return firstName + " " + lastName;
}
console.log(buildName("Bob"));                  // right, returns "Bob Smith"
console.log(buildName("Bob", undefined));       // right, returns "Bob Smith"
console.log(buildName("Bob", "Adams", "Sr."));  // error, too many parameters
console.log(buildName("Bob", "Adams"));         // right

在所有必須參數後面的帶默認初始化的參數都是可選的,與可選參數一樣,在調用函數的時候可以省略。

注意:與可選參數不同的是,默認參數不需要放在必須參數後面


4. 剩餘參數

必要參數,默認參數和可選參數有個共同點:它們錶示某一個參數。

有時,你想同時操作多個參數,或者你並不知道會有多少參數傳遞進來, 在TypeScript裏,你可以把所有參數收集到一個變量裏。

function greeting(firstName: string, ...restName: string[]) {
    
  return `Hello ${
      firstName} ${
      restName.join(' ')}!`;
}
console.log(greeting('Osama', 'bin', 'Muhammad', 'bin', 'Awad', 'bin', 'Laden'));
console.log(greeting('Laden'));
 //剩餘參數,會被當做個數不限的可選參數。可以一個都沒有,也可以有任意個

5. 箭頭函數

JavaScript裏,this的值在函數被調用的時候才會指定。 這是個既强大又靈活的特點,但需要花時間弄清楚函數調用的上下文是什麼,這不是一件很簡單的事,尤其是在返回一個函數或將函數當做參數傳遞的時候。

為了解决這個問題,我們在函數被返回時就綁好正確的this。而箭頭函數就能保存函數創建時的this值,而不是調用時的值。

//無參數,函數體代碼只有一行,則該行結果即為函數返回值
let greeting1 = () => `Hello TS!`;
console.log(greeting1());  // Hello TS!

//一個參數,函數體代碼只有一行,則該行結果即為函數返回值
let greeting2 = (name: string) => `Hello ${
      name}`;
console.log(greeting2('Kitty'));  // Hello Kitty

//兩個及以上的參數,函數體代碼只有一行,則該行結果即為函數返回值
let add1 = (n1: number, n2: number) => n1 + n2;
console.log(add1(1, 2));   // 3

//兩個及以上的參數,函數體代碼多於一行,則必須用{}包裹,且顯式給出return
let add2 = (n1: number, n2: number) => {
    
  let sum = n1 + n2;
  return sum;//改為sum++結果如何?
}
console.log(add2(1, 2));  // 3

六. 類Class

TypeScript 是面向對象的 JavaScript。
類描述了所創建的對象共同的屬性和方法。
TypeScript 支持面向對象的所有特性,比如 類、接口等。

1. 類的定義和使用

//類的定義和使用
class MyInfo {
     //class是關鍵字,類名默認全部大寫首字母
  name: string; //屬性
  weather: string; //屬性
  
  constructor(name: string, weather: string){
     //構造函數,一般用於初始化。如果沒有,TS會自動生成一個,以備用new創建類實例時調用。
    this.name = name;
    this.weather = weather;
  }
  printInfo(): void {
     //其它函數,無返回值
    console.log(`Hello, ${
      this.name}.`);
    console.log(`Today is ${
      this.weather}.`);
  }
}
let myData = new MyInfo('Jon', 'raining'); //使用new關鍵字生成對象,即該類的實例
myData.printInfo();

2. 類的屬性和函數的訪問權限

類中的屬性和函數都有訪問權限,默認為public即全局可訪問;protected是在類的內部和其子類的內部可訪問;private只能在該類內部可訪問。

//訪問權限
class MyInfo {
     
  public name: string; //public屬性,可省略
  private _weather: string; //私有屬性,習慣以_開頭進行命名
  
  constructor(name: string, weather: string){
     //構造函數,一般用於初始化
    this.name = name;
    this._weather = weather;
  }
  printInfo(): void {
     //其它函數
    console.log(`Hello, ${
      this.name}.`);
    console.log(`Today is ${
      this._weather}.`);
  }
}

let myData = new MyInfo('Jon, 'raining'); //使用new關鍵字生成對象
console.log(myData._weather); //error!
myData.printInfo(); 

3. 存取器

TypeScript支持通過gettersetter來截取對對象成員的訪問, 它能幫助你有效的控制對對象成員的訪問。
當在類外部時,建議設置gettersetter操作其private屬性,即使public屬性也如此。

//getter和setter
class MyInfo {
     
  private readonly _name: string; //私有屬性,外部不可訪問。readonly使其只能在初始化時賦值,以後不可更改。 
  private _weather: string; //私有屬性

  constructor(name: string, weather: string){
     //構造函數,一般用於初始化
    this._name = name;
    this._weather = weather;
  }
  get name(): string {
    
    return this._name;
  }
  set name(value: string) {
      //error! _name有readonly屬性
    this._name = value;
  }
  get weather(): string {
    
    return this._weather;
  }
  set weather(value: string) {
    
    this._weather = value;
  } 
}
  
let myData = new MyInfo('Jon', 'raining'); //使用new關鍵字生成對象
console.log(myData._name, myData._weather);
myData._weather = 'sunny'; //OK
myData._name = 'Wang'; //error!
console.log(myData);
 readonly關鍵字將屬性設置為只讀的,只讀屬性必須在聲明時或構造函數裏被初始化。
 只帶有get不帶有set的存取器自動被推斷為readonly。

4. 靜態屬性

static 關鍵字用於定義類的數據成員(屬性和方法)為靜態的,靜態成員可以直接通過類名調用。

//靜態屬性,內建或自定義,無需new即可使用
console.log(Math.round(89.64)); //90
console.log(Math.pow(2, 8)); //256
class MyStaticClass {
    
  static place = 'Earth';
  static printInfo() {
    
    console.log('We have only one Earth!');
  }
}
console.log(MyStaticClass.place);  //Earth
MyStaticClass.printInfo();

5. 繼承

類繼承使用關鍵字 extends,子類除了不能繼承父類的私有成員(方法和屬性)和構造函數,其他的都可以繼承。

class Animal {
    
    // 當構造函數傳入的參數加上了“訪問權限控制符”,則同時會聲明同名類屬性,並賦值
    constructor(public name: string) {
     }
    protected log(message: string) {
    
      console.log(message);
    }
    move(distanceInMeters: number = 0) {
            
      this.log(`${
      this.name} moved ${
      distanceInMeters}m.`);//請注意name來自何處
      this.log('==============');
    }
  }
  
  class Horse extends Animal {
    
    constructor(name: string) {
     
      super(name); // 通過super調用父類構造器
    }
    run(distanceInMeters = 50) {
     //自己獨有的函數
      this.log("Clop, clop..."); 
      super.move(distanceInMeters); // 通過super調用父類方法
    }
  }
  
  let tom: Horse = new Horse("Tommy");
  tom.run(66);

執行結果為:
在這裏插入圖片描述

注意:TypeScript 一次只能繼承一個類,不支持繼承多個類,但TypeScript 支持多重繼承(A 繼承 B,B 繼承 C)。

七. 模塊Module

  • 對於大型的項目,我們需要使用模塊進行管理。每個 .ts 文件就是一個模塊,通過 export 來對外部模塊暴露元素,通過 import 來引入模塊。
  • 模塊是自聲明的;兩個模塊之間的關系是通過在文件級別上使用importsexports建立的。

語法格式如下:

// 文件名 : SomeInterface.ts 
export interface SomeInterface {
     
   // 代碼部分
}

要在另外一個文件使用該模塊就需要使用 import 關鍵字來導入:

import someInterfaceRef = require("./SomeInterface");

八. 總結

TypeScript的設計解决了JavaScript的問題,讓程序模塊化,利於我們開發大型程序。
總的來說TypeScript還是比較容易上手的,因為它只是在JavaScript上擴展了語法。且編輯器提供精准的語法提示,讓我們更方便地實踐面向對象的編程。

九. 學習資料

https://typescript.bootcss.com/

原网站

版权声明
本文为[on the moon]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/177/202206252236011513.html