ES6 类
- 类的定义和实例
ES6 中的class用于定义类,使用
constructor定义构造函数,通过new生成实例的时候,会自动调用构造函数。
类class通过extends关键字实现继承,子类需要使用super关键字来调用父类的构造函数和方法。
class Animal {
public name;
constructor(name) {
this.name = name; //不执行次操作,this只是Animal类,自身不会存在name属性
}
sayHi() {
return `My name is ${this.name}`;
}
}
let a = new Animal('Jack');
console.log(a.sayHi()); // My name is Jack
class Cat extends Animal {
constructor(name) {
super(name); // 调用父类的 constructor(name)
console.log(this.name);
}
sayHi() {
return 'Meow, ' + super.sayHi(); // 调用父类的 sayHi()
}
}
let c = new Cat('Tom'); // Tom
console.log(c.sayHi()); // Meow, My name is Tom
- 存取器
类的getter和
setter可以改变属性的赋值和读取操作。
class Animal {
constructor(name) {
this.name = name;
}
get name() {
return 'Jack';
}
set name(value) {
console.log('setter: ' + value);
}
}
let a = new Animal('Kitty'); // setter: Kitty
a.name = 'Tom'; // setter: Tom
console.log(a.name); // Jack
当使用了存取器中的getter时setter也会同步生效,且无返回值
interface 一般用于规范三个东西,分别是函数、类和构造器
TS 中接口除了可用于对类的一部分行为进行抽象外,也常用于对对象的形状进行描述,接口定义时一般首字母大写。
一般定义接口后,赋值的时候参数也需要完全匹配,形状必须和接口的形状保持一致,当需要动态时就需要用到可选属性和任意属性的接口定义。
// 可选属性接口
interface Person {
name: string;
readonly id: number; //只读属性
age?: number;
}
let tom: Person = {
name: 'Tom',
id: 112,
};
// 任意属性接口
interface Person {
name: string;
age?: number;
// `[propName: string]` 定义了任意属性取 `string` 类型的值。
[propName: string]: string | number; //或者any
}
let tom: Person = {
name: 'Tom',
gender: 'male'
};
一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集
只读的约束存在于第一次给对象赋值的时候,而不是第一次给只读属性赋值的时候
- 函数 interface
函数 interface 可规范函数的参数和返回值
interface xxx{
(参数,...):返回值类型
}
interface SearchFn {
(key: string, page?: number): number[]
}
const search: SearchFn = function (key: string, page: number) {
return [1, 2, 3]
}
当函数是一个 interface 时,要求;
1、参数名可以不一致,但参数的类型必须与接口定义的对应,且参数可以少不可以多;
2、返回值必须要有,且与接口定义的一致。 2.类 interface 实现 implements 是面向对象中的一个重要概念,js 里一个类只能继承自另一个类,当不同类之间有公共的特性的时候,就可以把这些特性提取成一个接口(interfaces),用 implements 关键字来实现。
interface Alarm {
alert(): void;
}
class Door {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
interface Light {
lightOn(): void;
lightOff(): void;
}
class Car extends Door implements Alarm, Light {
alert() {
console.log('Car alert');
}
lightOn() {
console.log('Car light on');
}
lightOff() {
console.log('Car light off');
}
}
接口通过
extends继承类, 其原理就是在声明class Door的时候,除了会创建一个名为Door的类外,也会创建一个名为Door的类。
class Point {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
interface PointInstanceType {
x: number;
y?: number; //可选属性
}
// 等价于 interface Point3d extends PointInstanceType
interface Point3d extends Point {
z: number;
}
let point3d: Point3d = {x: 1, y: 2, z: 3};
PointInstanceType相比于Point,缺少了constructor方法,这是因为声明Point类时创建的Point类型是不包含构造函数的。另外,除了构造函数是不包含的,静态属性或静态方法也是不包含的(实例的类型当然不应该包括构造函数、静态属性或静态方法)。
一个类可以实现继承多个接口且继承某一类(继承类的时候,只会继承他的实例属性和方法,不包含今天属性和方法),接口也可以通过
extends继承接口,拥有所继承接口中的属性方法并且拓展自身的方法。
interface Alarm {
alert(): void;
}
interface LightableAlarm extends Alarm {
lightOn(): void;
lightOff(): void;
}