基本用法 (通过关键字 class)
// 基本用法
class VueService {constructor() {} // 构造器
}
类的约束(通过关键字 implements)
// 接口定义属性类型
interface VueProps {name: stringinit: () => void
}// 约束类
class VueService implements VueProps {name: stringconstructor(name: string) {this.name = name}init() {console.log(this.name)}
}const service = new VueService('校长')
service.init()
类的继承 (通过关键字 extends)
// 接口定义属性类型 (简单版的虚拟dom)
interface VNode {tag: stringtext?: stringchildren?: VNode[]
}
interface Dom {createElement: (el: string) => HTMLElementsetText: (el: HTMLElement, text: string) => voidrender: (data: VNode) => HTMLElement
}
class DomService implements Dom {constructor() { }createElement(el: string) {return document.createElement(el)}setText(el: HTMLElement, text: string) {el.textContent = text}render(data: VNode) {const root = this.createElement(data.tag)if (data.children && Array.isArray(data.children)) {data.children.forEach((item: any) => {const child = this.render(item)root.appendChild(child)})}if (data.text) {this.setText(root, data.text)}return root}
}interface Options {el: HTMLElement | string
}
interface VueProp {option: Optionsinit: () => void
}
class Vue extends DomService implements VueProp {option: Optionsconstructor(option: Options) {super()this.option = optionthis.init()}init() {const data: VNode = {tag: 'div',children: [{tag: 'p',text: '我是子节点P'},{tag: 'span',text: '我是子节点span'}]}const app = document.querySelector(`#${this.option.el}`)const child = this.render(data)app?.appendChild(child)}
}
new Vue({el: 'app'
})
类的修饰符 (readonly | private | protected | public)
- readonly 表示只读, 不能修改 (只能在构建的是否赋值一次)
- private 添加这个修饰符, 只能在自己内部使用 (自身外部都无法使用) [约束的类型里也不能出现]
- protected 只能给子类 和 自身内部使用 (外部无法使用)
- public 默认就是 public (可以给自身, 子类 以及外部使用)
super 原理 (父类的 prototype.constructor.call 指向的是父类的原型)
class Parent {constructor() {}render() {console.log(11111)}
}
class Child extends Parent {constructor() {super() // 父类的prototype.constructor.call 指向的是父类的原型this.render()}
}
class Parent {name: stringconstructor(name: string) {this.name = name}render() {console.log(11111)console.log(this.name)}
}
class Child extends Parent {constructor(name: string) {super(name) // 父类的prototype.constructor.call 指向的是父类的原型this.render()// super.render()}
}
new Child('小可爱')
静态方法 (通过关键字 static)
- 静态方法中的 this 只能指向静态方法或静态变量
- 静态方法只能用类的原型调用
class Parent {name: stringstatic age: number = 1233constructor(name: string) {this.name = name}render() {console.log(11111)console.log(this.name)}// 静态方法static version() {console.log('0.0.1')console.log(this.age)}// 静态方法static show() {this.version()}
}
const parents = new Parent('校长')
parents.render()Parent.show() // 静态方法的调用
get 与 set 方法
- 这两个方法 与 Object.defineProperty() 方法中的 set 与 get 很像
- 可以认为是个拦截器
interface Person {name: stringage: number[propName: string]: any
}class Student implements Person {name: stringage: numberclass: stringconstructor(name: string, age: number) {this.name = namethis.age = agethis.class= '一年级'}get info() {return `${this.name}_${this.age}岁_${this.class}`}set info(newValue) {this.class = newValue}
}const students = new Student('战三', 16)
console.log(students.info) // 战三_16岁_一年级
students.info = '高三'
console.log(students.info); // 战三_16岁_高三
抽象类 (通过 abstract 关键字)
- abstract 所定义的类是抽象类, 不能实例化
- abstract 所定义的方法, 都只是进行一个描述, 无法进行实现
- 可以用 派生类 来继承 抽象类
- 派生类中要实现抽象类中用 abstract 定义的方法
- 派生类可以被实例化
- 抽象类
// 抽象类
abstract class Vue {name: unknownconstructor(name?: string) {this.name = name}showName(): unknown { // 这里没有用abstract, 可以正常编译return this.name}abstract init(name: string): void // 这是用到abstract, 他只能进行描述, 无法实现像showName 的代码操作
}new Vue() // 这里会报错, 不能实例化abstract定义的抽象类
- 派生类
// 抽象类
abstract class Vue {name: unknownconstructor(name?: string) {this.name = name}showName(): unknown { // 这里没有用abstract, 可以正常编译return this.name}abstract init(name: string): void // 这是用到abstract, 他只能进行描述, 无法实现像showName 的代码操作
}
// 派生类
class Angular extends Vue {constructor() {super()}init(name: string) { // 在派生类中要实现抽象类中用abstract定义的方法this.name = name}
}
const angular = new Angular() // 派生类可以实例化
angular.init('小花')
console.log(angular.showName()); // 小花