1. 类的定义
ES6 提供了更接近传统语言的写法 class (类)这个概念,作为对象的模板。通过 class 关键字,可以定了类。
在 ES6 中 class 可以堪称时一个语法糖,它的大多数功能 ES5 都可以做,只不过 ES6 相比 ES5,对象的原型写法更加清晰,更像面向对象的写法。
kotlin
// js 定义类
// 定义类的关键字是class,类名的首字母要大写,类名后面要跟大括号,大括号里面是类的成员,成员可以是属性和方法。
class Index {
constructor() {
this.index = 0;
}
}
2. TS 定义类
在 TS 中是不允许直接在 constructor 定义变量的 需要在 constructor 上面先声明
typescript
// TS 定义类
class Person {
name: string; // 姓名
constructor(name: string, age: number) { // 构造函数
this.name = name; // 初始化姓名
}
}
但是这样会出现一个新问题,当我们定义了变量不去使用,也会报错。

通常的解决办法时给个默认值,或者进行赋值。
typescript
// 当定义参数未使用,可以给一个默认值
class Person1 {
name: string; // 姓名
age: number = 0; // 年龄
constructor(name: string, age: number) { // 构造函数
this.name = name; // 初始化姓名
}
}
class Person2 {
name: string; // 姓名
age: number; // 年龄
constructor(name: string, age: number) { // 构造函数
this.name = name; // 初始化姓名
this.age = age; // 初始化年龄
}
}
3. 类的修饰符
class 类中总共有四个修饰符:
3.1. public
使用 public 修饰符,表示该属性时公有的,可以让你定义的变量内部访问,也可以外部访问。如果不写默认就是 public
typescript
// public
class Person3 {
public name: string; // 姓名
public age: number; // 年龄
public constructor(name: string, age: number) { // 构造函数
this.name = name; // 初始化姓名
this.age = age; // 初始化年龄
}
}
3.2. private
使用 private 修饰符,表示该属性是私有的,代表定义的变量私有的只能在内部访问,不能在外部访问。
typescript
// private 只能在类内部访问,不能在类外部访问
class Person4 {
private name: string; // 姓名
private age: number; // 年龄
public constructor(name: string, age: number) { // 构造函数
this.name = name; // 初始化姓名
this.age = age; // 初始化年龄
}
}
3.3. protected
使用 protected 修饰符, 代表定义的变量私有的只能在内部和继承的子类中访问,不能在外部访问。
typescript
// protected 只能在类内部和子类中访问,不能在类外部访问
class Person5 { // 父类
protected name: string; // 姓名
protected age: number; // 年龄
public constructor(name: string, age: number) { // 构造函数
this.name = name; // 初始化姓名
this.age = age; // 初始化年龄
}
}
class Student extends Person5 { // 子类
public constructor(name: string, age: number) { // 构造函数
super(name, age); // 调用父类的构造函数
}
}
3.4. readonly
readonly 只能在类内部访问,不能在类外部访问,也不能修改
typescript
// readonly 只能在类内部访问,不能在类外部访问,也不能修改
class Person6 {
readonly name: string; // 姓名
readonly age: number; // 年龄
public constructor(name: string, age: number) { // 构造函数
this.name = name; // 初始化姓名
this.age = age; // 初始化年龄
}
}
4. static 静态属性和静态方法
我们用 static 定义的属性,不可以通过 this 去访问,只能通过类名去调用。
typescript
// static 静态属性和方法
class Person7 { // 父类
static name: string = '张三'; // 静态属性
static sayHello() { // 静态方法
console.log('Hello'); // 输出Hello
}
}
// 静态属性和方法可以通过类名访问,也可以通过实例访问
console.log(Person7.name); // 输出张三
Person7.sayHello(); // 输出Hello
Person7.sayHello1(); // 输出Hello Hello1
注意:如果两个函数都是 static 静态的也是可以通过 this 相互调用。
typescript
// static 静态属性和方法
class Person7 { // 父类
static name: string = '张三'; // 静态属性
static sayHello() { // 静态方法
console.log('Hello'); // 输出Hello
}
static sayHello1() { // 静态方法
this.sayHello(); // 输出Hello
console.log('Hello1'); // 输出Hello1
}
}
静态属性和静态方法可以继承
scala
// 静态属性和方法可以继承
class Student1 extends Person7 { // 子类
static sayHello2() { // 静态方法
this.sayHello(); // 输出Hello
console.log('Hello2'); // 输出Hello2
}
}
静态属性和静态方法可以重写
typescript
// 静态属性和方法可以重写
class Person7 { // 父类
static name: string = '张三'; // 静态属性
static sayHello() { // 静态方法
console.log('Hello'); // 输出Hello
}
static sayHello1() { // 静态方法
this.sayHello(); // 输出Hello
console.log('Hello1'); // 输出Hello1
}
}
console.log(Student2.name); // 输出张三
class Student2 extends Person7 { // 子类
static name: string = '李四'; // 静态属性
static sayHello() { // 静态方法
console.log('Hello'); // 输出Hello
}
}
console.log(Student2.name); // 输出李四
Student2.sayHello(); // 输出Hello
5. interface 定义类
TS interface 定义类 使用关键字 implements 后面跟 interface 的名字多个用逗号隔开 继承还是用extends
typescript
// interface 定义类
interface Person8 { // 接口
name: string; // 姓名
age: number; // 年龄
}
class Student3 implements Person8 { // 类
name: string; // 姓名
age: number; // 年龄
constructor(name: string, age: number) { // 构造函数
this.name = name; // 初始化姓名
this.age = age; // 初始化年龄
}
}
6. 抽象类
应用场景如果你写的类实例化之后毫无用处此时我可以把他定义为抽象类
或者你也可以把他作为一个基类 -> 通过继承一个派生类去实现基类的一些方法
我们看例子
csharp
// 当前代码无法被初始化
abstract class A {
public name:string
}
new A()
7. 视频案例
typescript
interface Options {
el: string | HTMLElement
}
interface VueCls {
init(): void
options: Options
}
interface Vnode {
tag: string
text?: string
props?: {
id?: number | string
key?: number | string | object
}
children?: Vnode[]
}
class Dom {
constructor() {
}
private createElement(el: string): HTMLElement {
return document.createElement(el)
}
protected setText(el: Element, text: string | null) {
el.textContent = text;
}
protected render(createElement: Vnode): HTMLElement {
const el = this.createElement(createElement.tag)
if (createElement.children && Array.isArray(createElement.children)) {
createElement.children.forEach(item => {
const child = this.render(item)
this.setText(child, item.text ?? null)
el.appendChild(child)
})
} else {
this.setText(el, createElement.text ?? null)
}
return el;
}
}