返回
Featured image of post TypeScript - 定義Class

TypeScript - 定義Class

TypeScript - 定義Class

Object Property

定義一個Object並且使用它,可以有很多呼叫方式。

var obj = {} // new Object()
obj.example = 'Hello World!'
console.log(obj.example) // output: 'Hello World!'
obj.functionController = function(){console.log('execute this function')}
console.log(obj.functionController()) // output: 'Hello World!'
obj['propertyName'] = 'propertyName'
console.log(obj.propertyName) // output: 'propertyName'

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
var mycar = new Car('Eagle', 'Talon TSi', 1993);
console.log(mycar) // output: { make: "Eagle", model: "Talon TSi" ,year: 1993 }

超級彈性去定義Object,當專案寫的複雜,每個人的寫作手法又不同就很容易出線詭異的錯誤。


ES6 Class

ECMAScript 的引入了 Class 的概念去定義 Class

class Polygon {
  // 使用 constructor 註冊此 class 預先加載定義
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
  // Getter
  get area() {
    return this.calcArea();
  }
  // Method
  calcArea() {
    return this.height * this.width;
  }
  // static
  static distance(a, b) {
      const dx = a.x - b.x;
      const dy = a.y - b.y;

      return Math.sqrt(dx*dx + dy*dy);
  }
}

// 使用 Class 需要將其 new 才會實體進專案
const square = new Polygon(10, 10);
console.log(square.area); //100
const p1 = new Polygon(5, 5);
const p2 = new Polygon(10, 10);

// 若是使用其 static 功能 不需要 new 實體
console.log(Polygon.distance(p1, p2)); // 7.0710678118654755

extends 繼承

class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(this.name + ' makes a noise.');
  }
  
  example() {
    console.log(this.name + 'example');
  }
}

class Dog extends Animal {
  speak() {
    console.log(this.name + ' barks.');
  }
}

var d = new Dog('Mitzie');
// 改寫原先的 function
d.speak(); // output: Mitzie barks. 
// 使用原先的 function
d.example(); // output: Mitzie example 

super 呼叫

class Cat {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(this.name + ' makes a noise.');
  }
}

class Lion extends Cat {
  speak() {
    super.speak();
    console.log(this.name + ' roars.');
  }
}

var l = new Lion('Fuzzy');
l.speak();
// Fuzzy makes a noise.
// Fuzzy roars.

ES6 一樣沒有 Private Method 的概念 所以任何人 實例出來即可使用 Class 內的功能。


TS Class

其實嚴格來說多了些 前綴讓 Class 微侷限住編譯,畢竟始終轉譯。

private

實例所建立之功能,預設 public

class Polygon {
  height: number;
  width: number;

  private privateCalcArea() {
    return this.height * this.width;
  }

  constructor(height:number, width:number) {
    this.height = height;
    this.width = width;
  }
  calcArea() {
    return this.privateCalcArea()
  }
}
var polygon = new Polygon(100,100);
console.log(polygon.calcArea()) // output: 10000
console.log(polygon.privateCalcArea()) // Error 編譯會出錯!

implements interface

檢查 Class 是否使用其功能而外之實作

interface Pingable {
  ping(): void;
}
 
class Sonar implements Pingable {
  ping() { console.log("ping!"); }
}
 
class Ball implements Pingable {
  // Error 編譯會出錯!
  pong() { console.log("pong!"); }
}

Generic

泛型,是一個高階技巧,也非常少使用,通常是重複性非常高的才會使用,通常也是被繼承之使用

class Box<Type> {
  private contents: Type;
  constructor(value: Type) {
    this.contents = value;
  }
}

結語

不管是 Class 還是 Function allow,就是一種開發習慣,只要適合團隊,基本上是沒什麼問題,像 Go 這語言就已經沒有 Class 這項功能了,兩種開發模式我都有嘗試過,其實只要定義清楚 Type ,哪種方式都不是問題。

  • Go 用 struct
  • TS 用 type
comments powered by Disqus