ES5模拟类的构造函数
function Person (name, age) {
this.name = name
this.age = age
}
Person.prototype.sayHello = function () {
console.log('my name is ' + this.name)
}
let p = new Person('smith', 25)
p.sayHello()
ES6的类
类的构成
- 构造函数方法
- 实例方法
- 获取函数get
- 设置函数set
- 静态类方法
- 静态类属性 (ES7+)
- 私有属性及方法 (ES13)
- 实例属性新写法 (ES13)
构造函数方法
constructor关键字用于在类定义块内部创建类的构造函数。方法名constructor会告诉解释器在使用new操作符创建类的新实例时,应该调用这个函数。构造函数的定义不是必需的,不定义构造函数相当于将构造函数定义为空函数。
class Person {
constructor (name, age) {
this.name = name
this.age = age
console.log('执行了')
}
}
let p = new Person('smith', 25)
console.log(p.name)
实例方法
es6类的实例方法默认定义在原型中
class Person {
constructor (name, age) {
this.name = name
this.age = age
}
sayHello () {
console.log('my name is ' + this.name)
}
}
let p = new Person('smith', 25)
p.sayHello()
console.log(p.hasOwnProperty('sayHello'))
console.log(p.__proto__.hasOwnProperty('sayHello'))
获取函数与设置函数
class Person {
constructor (name, age) {
this.name = name
this.age = age
}
get fullName () {
return 'Mr ' + this.name
}
set fullName (value) {
this.name = value
}
}
let p = new Person('smith', 25)
console.log(p.fullName)
p.fullName = 'david'
console.log(p.fullName)
静态方法
- 只能类本身调用
- 类静态方法中的this指向类本身而不是实例
class Person {
constructor (name, age) {
this.name = name
this.age = age
}
static create () {
console.log(this.name)
return new Person('default', 0)
}
}
let defaultPerson = Person.create()
console.log(defaultPerson)
静态类属性
ES6明确规定,class内部只有静态方法,没有静态属性,但ES7+ 提案也可以用static关键字增加类静态属性
class Person {}
Person.versionName = 'es6'
console.log(Person.versionName)
class Animal {
static versionName = 'es7'
}
console.log(Animal.versionName)
私有属性及方法
ES2022正式为class添加了私有属性,方法是在属性名之前使用#表示
class Person {
#gender = '男'
constructor (name, age) {
this.name = name
this.age = age
}
#sayHello () {
console.log('my name is ' + this.name)
}
}
实例属性新写法
class Person {
name
age
count = 0
constructor (name, age) {
this.name = name
this.age = age
}
add () {
this.count++
}
}
类的继承
extends关键字
类通过extends关键字实现继承,让子类继承父类的属性及方法
class Animal {}
class Dog extends Animal {}
let dog = new Dog()
super 关键字
ES5 的继承机制,是先创造一个独立的子类的实例对象,然后再将父类的方法添加到这个对象上面,即“实例在前,继承在后”。ES6 的继承机制,则是先将父类的属性和方法,加到一个空的对象上面,然后再将该对象作为子类的实例,即“继承在前,实例在后”。
class Animal {}
class Dog extends Animal {
constructor () {}
}
let dog = new Dog()
- super 作为函数使用,即代表调用父类的构造函数
class Animal {
constructor () {
console.log('animal')
}
}
class Dog extends Animal {
constructor () {
super()
console.log('dog')
}
}
let dog = new Dog()
- super 作为对象使用,在普通方法中,指向父类的的原型,在静态方法中,指向父类
class Father {
static name = '父亲'
say () {
console.log('father')
}
}
class Child extends Father {
say () {
console.log('child')
}
sayHello () {
super.say()
}
static sayName () {
console.log(super.name)
}
}
let child = new Child()
child.sayHello()
Child.sayName()
- 在子类普通方法中通过super调用父类方法时,方法内部this指向子类实例
由于this指向子类实例,所以如果通过super对某个属性赋值,这时super就是this,赋值的属性会变成子类实例的属性。
class Father {
#privateName = '1'
publicName = '2'
}
class Child extends Father {
say () {
console.log(this.publicName)
console.log(this.#privateName)
}
}
let child = new Child()
child.say()
TS的类
访问修饰符
- public 可以在任何地方被访问到,默认所有的属性和方法都是 public 的
- private 即私有属性与方法
- protected 修饰的属性或方法是受保护的,它和 private 类似,区别是它在子类中也是允许被访问的
class Animal {
protected name;
private age;
public constructor(name, age) {
this.name = name;
this.age = age
}
}
class Cat extends Animal {
constructor(name, age) {
super(name, age);
console.log(this.name);
console.log(this.age) // error
}
}
修饰符还可以使用在构造函数参数中,等同于类中定义该属性同时给该属性赋值,使代码更简洁。
class Person {
constructor (public name) {
}
}
readonly 只读属性关键字
class Person {
constructor (
public name,
public readonly age
) {}
}
let person = new Person('smith', 18)
person.age = 20
abstract 抽象关键字,定义抽象类或抽象方法
- 抽象类不允许被实例化
- 抽象类的抽象方法必须被子类实现
abstract class Animal {
constructor (public name) {
}
abstract sayHello()
}
class Dog extends Animal {
sayHello(): void {
console.log('name is' + this.name)
}
}
let cat = new Animal('小猫')
TS类与接口
类实现接口
实现(implements)是面向对象中的一个重要概念。一般来讲,一个类只能继承自另一个类,有时候不同类之间可以有一些共有的特性,这时候就可以把特性提取成接口(interfaces),用 implements 关键字来实现。这个特性大大提高了面向对象的灵活性。
import Table from '.../xxx.table'
interface common {
render(): void
getList(): void
}
interface loading {
loading(): void
}
class HomeTable implements common {
render () { ... }
getList () { ... }
}
class DashBoardTable extends Table implements common, loading {
render () { ... }
getList () { ... }
loading () { ... }
}
接口继承类,将类当做类型来使用
常见的面向对象语言中,接口是不能继承类的,但是在 TypeScript 中却是可以的
class Point {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
interface Point3d extends Point {
z: number;
}
let point3d: Point3d = {x: 1, y: 2, z: 3};
let point2d: Point = { x: 1, y: 2 }
|