在没有出现 es2015 之前在 JavaScript 中,我们都使用函数和原型来完成一个类的定义,但这对于熟悉其他面向对象的程序员(Java)来说非常的艰难,于是 es2015 将我们复杂的面向对象编程简化了不少,反而 TypeScript 对于它还有一些增强的扩展,我们可以一直使用它而不必等待下一版本的 JavaScript 标准实现,并且这和标准非常的类似。
基础
让我们来学习一个非常简单的类定义:
class World {
public country: string;
private max: number;
constructor(country: string){
this.country = country;
this.max = 110;
}
output() {
return this.country;
}
}
class Country extends World {
constructor(country: string){
super(country);
}
}
在这个范例中,我们既定义了类也完成了继承,看起来是不是和 es2015 几乎一样呢?当然它也有一些与 es2015 的标准稍有不同,因为 TypeScript 增强了关于 public private 之类的一些定义,这些定义可以在下一个 JavaScript 版本得到了实现,所以我们可以无需关心而正常的使用它。
修饰符
- public 外部程序可以自由的访问
- private 外部程序不可以自由的访问
- protected 与
private类似,唯一的不同是它可以在派生类中自由的访问 - readonly 与词同意,只读
- static 静态属性或方法
class StaticClass {
static orig = "";
static origFun = () => {}
}
存取器
如果你使用过 Object.defineProperty 那么一定理解如 getter setter 钩子的作用,在 TypeScript 的类中也定义了非常类似的东西,举个例子:
class Employee {
private _fullName: string;
constructor(){
this._fullName = "";
}
get fullName(): string {
return this._fullName;
}
set fullName(newValue: string) {
this._fullName = newValue;
}
}
const emp = new Employee();
emp.fullName = "";
比对一下编译之后的代码:
var Employee = /** @class */ (function () {
function Employee() {
this._fullName = "";
}
Object.defineProperty(Employee.prototype, "fullName", {
get: function () {
return this._fullName;
},
set: function (newValue) {
this._fullName = newValue;
},
enumerable: true,
configurable: true
});
return Employee;
}());
var emp = new Employee();
emp.fullName = "";
是不是发现了 Object.defineProperty ? 在使用存取器的过程中,唯一要注意的是如果只定义了 get 钩子而没有定义 set 钩子的话,这个属性将是 readonly。
抽象类
这个概念几乎在 JavaScript 从未存在过,如果有其他面向对象编程经验的程序应该会比较明白,说一个非常简单类似的设计,如iOS 中的 protocol:
abstract class Department {
constructor(public name: string) {
}
printName(): void {
console.log('Department name: ' + this.name);
}
abstract printMeeting(): void; // 必须在派生类中实现
}
class AccountingDepartment extends Department {
constructor() {
super('Accounting and Auditing'); // 在派生类的构造函数中必须调用 super()
}
printMeeting(): void {
console.log('The Accounting Department meets each Monday at 10am.');
}
generateReports(): void {
console.log('Generating accounting reports...');
}
}
范例
小明 最近很认真的在学习 TypeScript ,是什么给了他那么大的动力?如第一章里写的因为 涨薪,今天他在学习如何用一个类来操作 DOM 元素,对于此,他是这样设计的:
- 定义了一个 XDOM 类
- 定义了一个 inster 设置一个文本值
- 定义了一个 dom 属性
- 定义了一个 静态单例方法
- 定义了一个 setColor 的实例方法
class XDom {
static xdom: XDom | null;
static shareInstance = (): XDom => {
if (!XDom.xdom) {
XDom.xdom = new XDom();
}
return XDom.xdom;
}
public dom: HTMLElement | null;
constructor(){
this.dom = document.getElementById("class");
}
inster(text: string){
if (this.dom) {
this.dom.innerHTML = text;
}
}
setColor(color: string) {
if (this.dom) {
this.dom.style.color = color;
}
}
}
const xdom = XDom.shareInstance();
xdom.inster("icepy");
xdom.setColor("red");
如图:
完整的例子:github.com/welearnmore…