TypeScript-类、函数的一些要点
类
公共,私有与受保护的修饰符
public:在TypeScript中,成员默认为public,即使不使用修饰符。
private:当成员被标记成 private时,它就不能在声明它的类的外部访问。
protected:protected修饰符与 private修饰符的行为很相似,但有一点不同, protected成员在派生类中仍然可以访问。
class Person {
protected name: string;
constructor(name: string) { this.name = name; }
}
class Employee extends Person {
private department: string;
constructor(name: string, department: string) {
super(name)
this.department = department;
}
public getElevatorPitch() {
return `Hello, my name is ${this.name} and I work in ${this.department}.`;
}
}
let howard = new Employee("Howard", "Sales");
console.log(howard.getElevatorPitch());
console.log(howard.name); // 错误
注意,我们不能在 Person类外使用 name,但是我们仍然可以通过 Employee类的实例方法访问,因为 Employee是由 Person派生而来的。
构造函数也可以被标记成 protected。 这意味着这个类不能在包含它的类外被实例化,但是能被继承。
class Person {
protected name: string;
protected constructor(theName: string) { this.name = theName; }
}
// Employee 能够继承 Person
class Employee extends Person {
private department: string;
constructor(name: string, department: string) {
super(name);
this.department = department;
}
public getElevatorPitch() {
return `Hello, my name is ${this.name} and I work in ${this.department}.`;
}
}
let howard = new Employee("Howard", "Sales");
let john = new Person("John"); // 错误: 'Person' 的构造函数是被保护的.
readonly修饰符
你可以使用 readonly关键字将属性设置为只读的。 只读属性必须在声明时或构造函数里被初始化。
class Octopus {
readonly name: string;
readonly numberOfLegs: number = 8;
constructor (theName: string) {
this.name = theName;
}
}
let dad = new Octopus("Man with the 8 strong legs");
dad.name = "Man with the 3-piece suit"; // 错误! name 是只读的.
存取器
TypeScript支持通过getters/setters来截取对对象成员的访问。
let passcode = "secret passcode";
class Employee {
private _fullName: string;
get fullName(): string {
return this._fullName;
}
set fullName(newName: string) {
if (passcode && passcode == "secret passcode") {
this._fullName = newName;
}
else {
console.log("Error: Unauthorized update of employee!");
}
}
}
let employee = new Employee();
employee.fullName = "Bob Smith";
if (employee.fullName) {
alert(employee.fullName);
}
函数
可选参数和默认参数
TypeScript里的每个函数参数都是必须的。 可以传递 null或undefined作为参数,不可以缺失特定的参数。 也就是传递给一个函数的参数个数必须与函数期望的参数个数一致。注意在JavaScript中参数是可选的,没值就是undefined,在TypeScript中可以用?去实现可选参数。如:
function buildName(firstName: string, lastName?: string) {
if (lastName)
return firstName + " " + lastName;
else
return firstName;
}
tips:可选参数必须跟在必须参数后面。
在TypeScript里,我们也可以为参数提供一个默认值当用户没有传递这个参数或传递的值是undefined时。 即默认参数。
function buildName(firstName: string, lastName = "Smith") {
return firstName + " " + lastName;
}
与普通可选参数不同的是,带默认值的参数不需要放在必须参数的后面。
剩余参数
在TypeScript里,可以把所有参数收集到一个变量里:
function buildName(firstName: string, ...restOfName: string[]) {
return firstName + " " + restOfName.join(" ");
}
剩余参数会被当做个数不限的可选参数。 可以一个都没有,同样也可以有任意个。
重载
在TypeScript中,为同一个函数提供多个函数类型定义来进行函数重载。 编译器会根据这个列表去处理函数的调用。
let suits = ["hearts", "spades", "clubs", "diamonds"];
function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any {
// Check to see if we're working with an object/array
// if so, they gave us the deck and we'll pick the card
if (typeof x == "object") {
let pickedCard = Math.floor(Math.random() * x.length);
return pickedCard;
}
// Otherwise just let them pick the card
else if (typeof x == "number") {
let pickedSuit = Math.floor(x / 13);
return { suit: suits[pickedSuit], card: x % 13 };
}
}
重载的pickCard函数在调用的时候会进行正确的类型检查。
注意,function pickCard(x): any并不是重载列表的一部分,因此这里只有两个重载:一个是接收对象另一个接收数字。 而其它参数调用该方法会产生错误。