# JS的类模块

5 min read
Table of Contents

在 es5 中主要是通过构造函数方式和原型方式来定义一个类,在 es6 中我们可以通过 class 来定义一个类。

ES5

在 es5 中主要是通过构造函数方式和原型方式来定义一个类,且一般以大写字母开头。

ES6 中的类模块转换成 ES5。以下是根据 TSC 转换情况,

  • 类 -> 函数
  • 方法 -> prototype 方法
  • 构造器参数 -> 参数
  • 静态方法 -> 属性
class Log {
constructor(height, width) {
this.height = height
this.width = width
}
static displayName = 'Point'
run(value) {
console.log(value)
return value
}
}

TS 编译之后的结果

var Log = /** @class */ (function () {
function Log(height, width) {
this.height = height
this.width = width
}
Log.prototype.run = function (value) {
console.log(value)
return value
}
Log.displayName = 'Point'
return Log
})()

ES6

在 ES6 中定义一个类使用关键字 class。

class Rectangle {
constructor(height, width) {
this.height = height
this.width = width
}
}

构造器

constructor 构造器是用于创建和初始化一个使用 class 创建的对象。一个类中只能包含一个构造器。

一个构造器可以使用 super 关键字来调用父类的构造函数。

对于类和子类来说,构造器并不是必须的。如果省略的话,那么二者都会自动提供一个默认构造器。具体来说,默认子类构造器会自动调用父类的构造器并传递所有参数。类似代码如下:

constructor(...args) {
super(...args);
}

static

通过 static 关键字定义静态方法和静态属性。静态成员(属性和方法)的调用不需要实例化他们的类,也不能通过类的实例来调用。静态方法通常用于为应用创建实用性函数,而静态属性通常用于缓存、固定配置或者其他不需要重复的实例数据。

在类生命了 static 方法其实就是直接添加到这个类的函数对象上,而不是在这个函数对象的 protytpe 对象上。

class Point {
constructor(x, y) {
this.x = x
this.y = y
}
// 静态域
static Name = 'Point'
// 静态方法
static getName() {
return this.Name
}
static position(p) {
return `(${p.x}, ${p.y})`
}
}
// 实例化 p1
const p1 = new Point(2, 5)
// 访问静态域和静态方法
console.log(Point.Name) // "Point"
console.log(Point.getName()) // "Point"
console.log(Point.position(p1)) // (2, 5)

extends

extends 关键字在类声明或类表达式中用于创建一个类的子类。

class Foo {
constructor(a, b) {
this.x = a
this.y = b
}
gimmeXY() {
return this.x * this.y
}
}
class Bar extends Foo {
constructor(a, b, c) {
super(a, b)
this.z = c
}
gimmeXYZ() {
return super.gimmeXY() * this.z
}
}
var b = new Bar(5, 15, 25)
b.x // 5
b.y // 15
b.z // 25
b.gimmeXYZ() // 1875

在 extends 经常会使用 super,那是因为子类中经常会调用父类的的属性或者方法。

super

super 关键字被用来调用父类相应的方法。super 在构造器中,自动指向“父构造器”,在上面的例子中就是 Foo(..)。在方法中,super 会指向 “父对象”,这样就可以访问其属性/方法了,比如上面的 super.gimmeXY()。

如果子类中定义了构造函数,那么它必须先调用 super 才能使用 this。注意,是在子类的构造函数才需要。

ES5 的类与 ES6 的 class 区别

  1. class 类必须 new 调用,不能直接执行。

    class 类执行的话会报错,而 ES5 中的类和普通函数并没有区别。

  2. class 类不存在变量提升

    ES5 函数声明会有变量提升,而 class 是没有将类的定义提升到顶部,这也是 TS 将 class 转成 ES5 的时候用到函数表达式的原因。

  3. class 类有 static 静态方法

    static 静态方法只能通过类调用,不会出现在实例上;另外如果静态方法包含 this 关键字,这个 this 指的是类,而不是实例。

    static 静态属性和方法都不可以被子类继承。

参考链接


More Posts

# 虚拟DOM

2 min read

Virtual DOM,虚拟 DOM 是 React 创建的一个树型自定义对象来代表真实 DOM。使得 React 可以快速操作这些对象,而不需实际接触到真实的 DOM 或者通过使用 DOM API。最后,当需要渲染的时候,可以使用这个虚拟 DOM 计算得出真实的 DOM,并把它渲染到浏览器上。