声明
class CustomStack {
maxSize: number;
size: number;
stack: Array<number>;
constructor(maxSize: number) {
this.maxSize = maxSize;
this.size = 0;
this.stack = [];
}
}
对象
const objArr: {name: sring}[] = [
new Teacher(),
{
name: 'Jack'
}
]
类型抽象
// 类型别名
type Person {
name: String
}
// 类
class Person {
name: String
}
const teacher: Person = {
name: "Jack"
}
对象解构
let person = {
name: "Semlinker",
gender: "Male",
};
let { name, gender } = person;
对象展开运算符
let person = {
name: "Semlinker",
gender: "Male",
address: "Xiamen",
};
// 组装对象
let personWithAge = { ...person, age: 33 };
// 获取除了某些项外的其它项
let { name, ...rest } = person;
类
在 TypeScript 中,我们可以通过 Class
关键字来定义一个类:
class Person {
name = 'Jack'
getName() {
return this.name;
}
}
const person = new Person()
person.getName()
// 继承, 子类方法覆盖父类方法
class Teacher extends Person {
getTeacherName() {
return 'teacher'
}
// getName() {
// return 'Lee'
// }
// 继承父类方法
getName() {
return super.getName() + 'Lee'
}
}
属性:
在面向对象语言中,类是一种面向对象计算机编程语言的构造,是创建对象的蓝图,描述了所创建的对象共同的属性和方法。
属性:
- 静态属性, static作为前缀
- 成员属性
操作静态属性(如何读取和修改)
📢 更规范写法, 私有属性/方法用下划线开头
class Person {
constructor (private _name: string) {}
get name() {
return this._name
}
set name(name: string) {
this._name = name
}
}
const person = new Person('Jack')
console.log(person.name) // Jack
person.name = 'Lee'
console.log(person.name) // Lee
静态属性应用: 实现单例模式
单例模式, 永远只生成一个实例
直接挂在类的下边, 定义私有静态属性存放事例, 从而限制再一次的构造。
class Person {
private static instance: Person;
private constructor(name: string) {}
static getInstance(name: string) {
if (!this.intance) {
new Person(name)
}
return this.instance
}
}
const p1 = Person.getInstance('Jack')
const p2 = Person.getInstance('Lee')
console.log(p1.name) // Jack
console.log(p2.name) // Lee
readonly 修饰器
class Person() {
public readonly name: string;
constructor(name: string) {
this.name = name;
}
}
方法:
- 静态方法
-
成员属性 VS 静态属性区别❓
```typescript 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 代码:
```typescript
"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");
访问类型
- private (私有属性), 允许内部调用
- public (公共属性),允许在类内外调用
- protected , 允许类内及继承子类调用 ```typescript class Employee { private _fullName: string = ‘Jack’; }
var a = new Employee();
// 非法外部调用报error console.log(a._fullName); // error TS2341: Property ‘_fullName’ is private and only accessible within class ‘Employee’.
<a name="iVl8s"></a>
### 访问器
通过 `getter` 和 `setter` 方法来实现数据的封装和有效性校验,防止出现异常数据。<br />set、get作为函数前缀, 调用get函数, 后无需 '()'。
```typescript
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);
}
构造器
传统写法:
class Person {
public name: string;
constructor(name: string) {
this.name = name;
}
}
const p = new Person('Jack');
console.log(p.name);
// Jack
简化语法: 直接在构造器传参中定义public, 减少操作
class Person {
constructor(public name: string) { }
}
子类构造器, 需要子类内部super调父类构造器
class Person {
constructor(public name: string) {
}
}
class Teacher extends Person {
constructor(public age: number) {
super('Lucy');
}
}
let t = new Teacher(36);
console.log(t.name, t.age);
// Lucy 36
类的继承
继承 (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();
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);
- 私有字段不能在包含的类之外访问,甚至不能被检测到。
抽象类
抽象类, 只能被继承, 不能被new调用构造函数。
// 抽象类
abstract class Geom {
constructor (public width: number) {}
getType() {
return 'Gemo';
}
// 抽象方法
abstract getArea(): number;
}
class Circle extends Geom {
getArea() {
return 123;
}
}
class Square extends Geom {}
class Triangle extends Geom {}