访问权限修饰符
通过访问权限修饰符可以指定类中的属性、方法能够在哪些范围内被使用。
修饰符 | 说明 |
---|---|
public | 被 public |
关键字修饰的类属性和类方法可以在任何地方使用(当前类、子类、实例) | |
private | 被 private |
关键字修饰的类属性和类方法只能在当前类中使用。 | |
protected | 被 protected |
关键字修饰的类属性和类方法可以在当前类和子类中使用。 |
public 公开的
public 修饰符是可以被省略的,不加修饰符时默认是 public。
class Vehicle {
wheels: number = 240;
constructor() {
this.drive(); // 可以在父类中调用
};
public drive() {
console.log("drive");
};
};
class Car extends Vehicle {
brand: string = "BMW";
super.drive(); // 可以在子类中调用
};
// 创建实例
const car = new Car();
car.drive(); // 可以在实例对象中调用
private 私有的
private 只能在当前类中使用。
class Vehicle {
wheels: number = 240;
constructor() {
this.drive(); // 可以在父类中调用
};
private drive() {
console.log("drive");
};
};
class Car extends Vehicle {
brand: string = "BMW";
// super.drive(); // 无法在子类中调用
};
// 创建实例
const car = new Car();
// car.drive(); // 无法在实例对象中调用
protected 受保护的
可以在当前类和子类中使用。
class Vehicle {
wheels: number = 240;
constructor() {
this.drive(); // 可以在父类中调用
};
private drive() {
console.log("drive");
};
};
class Car extends Vehicle {
brand: string = "BMW";
super.drive(); // 可以在子类中调用
};
// 创建实例
const car = new Car();
// car.drive(); // 无法在实例对象中调用
Getter 和 Setter
是对属性访问的封装,通过它们可以实现对属性访问的设置的监听。获取属性值时使用
Getter
,修改属性值时使用Setter
。
class Employee {
private _salary: number; // 私有属性:薪资
construction(salary: number) {
this._salary = salary;
};
// 获取私有属性
get salary() {
return this._salary;
};
// 修改私有属性
set salary(salary: number) {
this._salary = salary;
};
};
const e = new Employee(10000);
e.salary(); // 10000
e.salary(20000); // 传参,调用set方法修改私有属性
参数属性
TypeScript
提供了特殊的语法将构造函数参数转换为具有相同名称的类属性。这些称为参数属性,是通过在构造函数参数前面加上权限修饰符public
、private
、protected
或readonly
之一来创建的。
class Vehicle {
// 省略定义的类属性
// color: string; maxSpeed: number;
// 通过给构造函数上的参数加上修饰符,来省略定义类属性
constructor( public color: string, public maxSpeed: number ) {
...
};
};
const v1 = new Vehicle("white", 240);
console.log(v1); // { color: "white", maxSpeed: 240 }
索引签名
在
TypeScript
中为对象动态添加属性默认是不被允许的,需要使用索引签名,通过索引签名可以在不确定属性名称的情况下限制对象属性的类型以及对象值的类型。
在不确定属性名称的情况下限制属性的类型,意味着我们可以动态的为对象添加任意属性,但属性类型要符合要求。
// 很多属性类型是一样的,只有属性名称不一样
class SeatAssignment {
// 需要多少属性就要定义多少属性名。
A1: string,
A2: string,
A3: string,
...
};
const seat = new SetaAssignment();
seat.A1 = "张三";
seat.A2 = "李四";
seat.A3 = "王五";
// 语法格式
[属性名称: 属性名称类型]: 属性值类型
// 索引签名可以在不限制属性名称的情况下,限制属性的类型以及属性值的类型。
class SetaAssignment {
// 只需要定义一个就可以创建多个符合规定的属性
[seatNumber: string]: string,
};
const seat = new SetaAssignment();
seat.A1 = "张三";
seat.A2 = "李四";
// 默认会执行 toString 方法来转换为string类型,但是对象和布尔值不行
seat[1] = "王五";
console.log(seat["1"]); // 王五
静态成员
在类中被
static
关键字修饰的类属性和类方法被叫做静态成员,静态成员属于类,所以访问静态成员的方式是类名.静态成员名称
。
class Person {
static name: string = "张三";
};
// 访问
console.log(Person.name);
const p = new Person();
// p.name // 实例无法访问静态属性
对于该类的任何对象而言,静态成员就是公共的存储单元,该类的任何对象访问它时,取到的都是相同的值,同样任何一个类的对象去修改它时,也都是在对同一个内存单元做操作,所以静态属性主要用在各个对象都要共享的数据。
class Rich {
static count = 0;
constructor() {
// 记录创建了几次对象
Rich.count++;
}
}
静态成员始终存在于内存,而非静态成员需要实例化才可以分配到内存,所以静态成员不能访问非静态成员,非静态成员可以访问类中的静态成员。
class Rich {
// 静态成员
static count = 0;
constructor() {
Rich.count++;
};
// 非静态成员可以访问静态成员
getCount() {
return Rich.count;
};
static fn() {
// 静态成员不能访问非静态成员
// this.getCount();
}
}