# JS的类模块
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})` }}
// 实例化 p1const 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 // 5b.y // 15b.z // 25b.gimmeXYZ() // 1875在 extends 经常会使用 super,那是因为子类中经常会调用父类的的属性或者方法。
super
super 关键字被用来调用父类相应的方法。super 在构造器中,自动指向“父构造器”,在上面的例子中就是 Foo(..)。在方法中,super 会指向 “父对象”,这样就可以访问其属性/方法了,比如上面的 super.gimmeXY()。
如果子类中定义了构造函数,那么它必须先调用 super 才能使用 this。注意,是在子类的构造函数才需要。
ES5 的类与 ES6 的 class 区别
-
class 类必须 new 调用,不能直接执行。
class 类执行的话会报错,而 ES5 中的类和普通函数并没有区别。
-
class 类不存在变量提升
ES5 函数声明会有变量提升,而 class 是没有将类的定义提升到顶部,这也是 TS 将 class 转成 ES5 的时候用到函数表达式的原因。
-
class 类有 static 静态方法
static 静态方法只能通过类调用,不会出现在实例上;另外如果静态方法包含 this 关键字,这个 this 指的是类,而不是实例。
static 静态属性和方法都不可以被子类继承。
参考链接
- MDN: Classes
- 《你不知道的 Javascriopt(下)》第二部分 3.4
- es5 中的类和 es6 中的 class 有什么区别?