TypeScript 类
作者:Seiya
时间:2019年08月02日
ES6 中类的用法
属性和方法
使用 class 定义类,使用 constructor 定义构造函数。通过 new 生成新实例的时候,会自动调用构造函数:
class Animal {
constructor(name) {
this.name = name;
}
sayHi() {
return `My name is ${this.name}`;
}
}
let a = new Animal('Jack');
console.log(a.sayHi()); // My name is Jack
类的继承
使用 extends 关键字实现继承,子类中使用 super 关键字来调用父类的构造函数和方法:
class Cat extends Animal {
constructor(name) {
super(name); // 调用父类的 constructor(name)
console.log(this.name);
}
sayHi() {
return 'Meow, ' + super.sayHi(); // 调用父类的 sayHi()
}
}
let c = new Cat('Tom'); // Tom
console.log(c.sayHi()); // Meow, My name is Tom
存取器
使用 getter 和 setter 可以改变属性的赋值和读取行为:
class Animal {
constructor(name) {
this.name = name;
}
get name() {
return 'Jack';
}
set name(value) {
console.log('setter: ' + value);
}
}
let a = new Animal('Kitty'); // setter: Kitty
a.name = 'Tom'; // setter: Tom
console.log(a.name); // Jack
静态方法
使用 static 修饰符修饰的方法称为静态方法,它们不需要实例化,而是直接通过类来调用:
class Animal {
static isAnimal(a) {
return a instanceof Animal;
}
}
let a = new Animal('Jack');
Animal.isAnimal(a); // true
a.isAnimal(a); // TypeError: a.isAnimal is not a function
ES7 中类的用法
ES7 中有一些关于类的提案,TypeScript 也实现了它们,这里做一个简单的介绍。
实例属性
ES6 中实例的属性只能通过构造函数中的 this.xxx 来定义,ES7 提案中可以直接在类里面定义:
class Animal {
name = 'Jack';
constructor() {
// ...
}
}
let a = new Animal();
console.log(a.name); // Jack
静态属性
ES7 提案中,可以使用 static 定义一个静态属性:
class Animal {
static num = 42;
constructor() {
// ...
}
}
console.log(Animal.num); // 42
TypeScript 中类的用法
public、private 和 protected
TypeScript 可以使用三种访问修饰符(Access Modifiers),分别是 public、private 和 protected。
public
: 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public 的private
: 修饰的属性或方法是私有的,不能在声明它的类的外部访问protected
: 修饰的属性或方法是受保护的,它和 private 类似,区别是它在子类中也是允许被访问的
注意:
TypeScript 编译之后的代码中,并没有限制 private 属性在外部的可访问性。
抽象类
abstract
用于定义抽象类和其中的抽象方法。
- 抽象类是不允许被实例化的:
abstract class Animal {
public name;
public constructor(name) {
this.name = name;
}
public abstract sayHi();
}
let a = new Animal('Jack'); // error
- 抽象类中的抽象方法必须被子类实现:
abstract class Animal {
public name;
public constructor(name) {
this.name = name;
}
public abstract sayHi();
}
class Cat extends Animal { // error(没有实现抽象方法 sayHi)
public eat() {
console.log(`${this.name} is eating.`);
}
}
let cat = new Cat('Tom');
注意:
即使是抽象方法,TypeScript 的编译结果中,仍然会存在这个类。
类的类型
给类加上 TypeScript 的类型很简单,与接口类似:
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
sayHi(): string {
return `My name is ${this.name}`;
}
}
let a: Animal = new Animal('Jack');
console.log(a.sayHi()); // My name is Jack