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