八、TypeScript 数组
8.1 数组解构
let x: number; let y: number; let z: number;let five_array = [0,1,2,3,4];[x,y,z] = five_array;
8.2 数组展开运算符
let two_array = [0, 1];let five_array = [...two_array, 2, 3, 4];
8.3 数组遍历
let colors: string[] = ["red", "green", "blue"];for (let i of colors) {console.log(i);}
九、TypeScript 对象
9.1 对象解构
let person = {name: "Semlinker",gender: "Male",};let { name, gender } = person;
9.2 对象展开运算符
let person = {name: "Semlinker",gender: "Male",address: "Xiamen",};// 组装对象let personWithAge = { ...person, age: 33 };// 获取除了某些项外的其它项let { name, ...rest } = person;
十、TypeScript 接口
在面向对象语言中,接口是一个很重要的概念,它是对行为的抽象,而具体如何行动需要由类去实现。
TypeScript 中的接口是一个非常灵活的概念,除了可用于对类的一部分行为进行抽象以外,也常用于对「对象的形状(Shape)」进行描述。
10.1 对象的形状
interface Person {name: string;age: number;}let Semlinker: Person = {name: "Semlinker",age: 33,};
10.2 可选 | 只读属性
interface Person {readonly name: string;age?: number;}
只读属性用于限制只能在对象刚刚创建的时候修改其值。此外 TypeScript 还提供了 ReadonlyArray<T> 类型,它与 Array<T> 相似,只是把所有可变方法去掉了,因此可以确保数组创建后再也不能被修改。
let a: number[] = [1, 2, 3, 4];let ro: ReadonlyArray<number> = a;ro[0] = 12; // error!ro.push(5); // error!ro.length = 100; // error!a = ro; // error!
十一、TypeScript 类
11.1 类的属性与方法
在面向对象语言中,类是一种面向对象计算机编程语言的构造,是创建对象的蓝图,描述了所创建的对象共同的属性和方法。
在 TypeScript 中,我们可以通过 Class 关键字来定义一个类:
class Greeter {// 静态属性static cname: string = "Greeter";// 成员属性greeting: string;// 构造函数 - 执行初始化操作constructor(message: string) {this.greeting = message;}// 静态方法static getClassName() {return "Class name is Greeter";}// 成员方法greet() {return "Hello, " + this.greeting;}}let greeter = new Greeter("world");
那么成员属性与静态属性,成员方法与静态方法有什么区别呢?这里无需过多解释,我们直接看一下以下编译生成的 ES5 代码:
"use strict";var Greeter = /** @class */ (function () {// 构造函数 - 执行初始化操作function Greeter(message) {this.greeting = message;}// 静态方法Greeter.getClassName = function () {return "Class name is Greeter";};// 成员方法Greeter.prototype.greet = function () {return "Hello, " + this.greeting;};// 静态属性Greeter.cname = "Greeter";return Greeter;}());var greeter = new Greeter("world");
11.2 访问器
在 TypeScript 中,我们可以通过 getter 和 setter 方法来实现数据的封装和有效性校验,防止出现异常数据。
let passcode = "Hello TypeScript";class Employee {private _fullName: string;get fullName(): string {return this._fullName;}set fullName(newName: string) {if (passcode && passcode == "Hello TypeScript") {this._fullName = newName;} else {console.log("Error: Unauthorized update of employee!");}}}let employee = new Employee();employee.fullName = "Semlinker";if (employee.fullName) {console.log(employee.fullName);}
11.3 类的继承
继承 (Inheritance) 是一种联结类与类的层次模型。指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间最常见的关系。
继承是一种 is-a 关系:
在 TypeScript 中,我们可以通过 extends 关键字来实现继承:
class Animal {name: string;constructor(theName: string) {this.name = theName;}move(distanceInMeters: number = 0) {console.log(`${this.name} moved ${distanceInMeters}m.`);}}class Snake extends Animal {constructor(name: string) {super(name);}move(distanceInMeters = 5) {console.log("Slithering...");super.move(distanceInMeters);}}let sam = new Snake("Sammy the Python");sam.move();
11.4 ECMAScript 私有字段
在 TypeScript 3.8 版本就开始支持ECMAScript 私有字段,使用方式如下:
class Person {#name: string;constructor(name: string) {this.#name = name;}greet() {console.log(`Hello, my name is ${this.#name}!`);}}let semlinker = new Person("Semlinker");semlinker.#name;// ~~~~~// Property '#name' is not accessible outside class 'Person'// because it has a private identifier.
与常规属性(甚至使用 private 修饰符声明的属性)不同,私有字段要牢记以下规则:
- 私有字段以
#字符开头,有时我们称之为私有名称; - 每个私有字段名称都唯一地限定于其包含的类;
- 不能在私有字段上使用 TypeScript 可访问性修饰符(如 public 或 private);
- 私有字段不能在包含的类之外访问,甚至不能被检测到。
