从 ECMAScript 6 开始,JavaScript 中有了类(class)这个概念。但需要注意的是,这并不是说:JavaScript 从此变得像其它基于类的面向对象语言一样,有了一种全新的继承模型。JavaScript 中的类只是 JavaScript 现有的、基于原型的继承模型的一种语法包装(语法糖),它能让我们用更简洁明了的语法实现继承。
定义类
ES6 中的类实际上就是个函数,而且正如函数的定义方式有函数声明和函数表达式两种一样,类的定义方式也有两种,分别是:
类声明
类声明是定义类的一种方式,就像下面这样,使用 class
关键字后跟一个类名(这里是 Ploygon),就可以定义一个类。
class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
}}123456
变量提升
类声明和函数声明不同的一点是,函数声明存在变量提升现象,而类声明不会。也就是说,你必须先声明类,然后才能使用它,否则代码会抛出 ReferenceError
异常,像下面这样:
var p = new Polygon(); // ReferenceError
class Polygon {}123
类表达式
类表达式是定义类的另外一种方式,就像函数表达式一样,在类表达式中,类名是可有可无的。如果定义了类名,则该类名只有在类体内部才能访问到。
// 匿名类表达式var Polygon = class {
constructor(height, width) {
this.height = height;
this.width = width;
}};
// 命名类表达式var Polygon = class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
}};123456789101112131415
类体和方法定义
类的成员需要定义在一对花括号 {}
里,花括号里的代码和花括号本身组成了类体。类成员包括类构造器和类方法(包括静态方法和实例方法)。
严格模式
类体中的代码都强制在 严格模式 中执行,即便你没有写 "use strict"
。
构造器(constructor 方法)
constructor
方法是一个特殊的类方法,它既不是静态方法也不是实例方法,它仅在实例化一个类的时候被调用。一个类只能拥有一个名为 constructor
的方法,否则会抛出 SyntaxError
异常。
在子类的构造器中可以使用 super
关键字调用父类的构造器。
原型方法
See also 方法定义.
class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
}
get area() {
return this.calcArea()
}
calcArea() {
return this.height * this.width;
}
}
静态方法
static
关键字用来定义类的静态方法。 静态方法是指那些不需要对类进行实例化,使用类名就可以直接访问的方法。静态方法经常用来作为工具函数。
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
static distance(a, b) {
const dx = a.x - b.x;
const dy = a.y - b.y;
return Math.sqrt(dx*dx + dy*dy);
}
}
const p1 = new Point(5, 5);
const p2 = new Point(10, 10);
console.log(Point.distance(p1, p2));
使用 extends
关键字创建子类
extends
关键字可以用来创建继承于某个类的子类。
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
speak() {
console.log(this.name + ' barks.');
}
}
为内置对象类型(Array,RegExp等)创建子类
TBD
使用 super
关键字引用父类
super
关键字可以用来调用其父类的构造器或者类方法
class Cat {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Lion extends Cat {
speak() {
super.speak();
console.log(this.name + ' roars.');
}
}
规范
Specification | Status | Comment |
---|---|---|
ECMAScript 2015 (6th Edition, ECMA-262) Class definitions |
STStandard | Initial definition. |
浏览器兼容性