ES6之Class类

1. 类的由来

JavaScript 语言中,生成实例对象的传统方法是通过构造函数,下面我们来看一段代码:

1
2
3
4
5
6
7
8
9
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return this.x + ', ' + this.y;
};
var p = new Point(1, 2);
console.log(p); // Point {x: 1, y: 2}

但是上面这种写法跟传统的面向对象语言(比如 C++ 和 Java)差异很大,很容易让新学习这门语言的程序员感到困惑。

ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
我们将上面的代码用Class来进行一个改写,代码如下所示:

1
2
3
4
5
6
7
8
9
10
class Point {
constructor(x, y) { // constructor方法,这就是构造方法
this.x = x; // this关键字则代表实例对象
this.y = y;
}
toString() { // 注意:定义“类”的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了,方法之间不需要逗号分隔,加了会报错
return '(' + this.x + ', ' + this.y + ')';
}
}
// 此时你可以看到:ES5的构造函数Point,对应ES6 的Point类的构造方法。

2. constructor方法

constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。
注意:一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。

1
2
3
4
5
6
7
8
class Point {
}

// 等价于
class Point {
// 定义了一个空的类Point,JavaScript 引擎会自动为它添加一个空的constructor方法。
constructor() {} // 自动添加的
}

3. 类的实例

生成类的实例的写法,与 ES5 完全一样,也是使用new命令。注意:如果忘记加上new,像函数那样调用Class,将会报错。

1
2
3
4
5
6
7
8
9
class Point {
// ...
}

// 报错
var point = Point(2, 3);

// 正确
var point = new Point(2, 3);

与 ES5 一样,实例的属性除非显式定义在其本身(即定义在this对象上),否则都是定义在原型上(即定义在class上)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//定义类
class Point {

constructor(x, y) {
this.x = x;
this.y = y;
}

toString() {
return this.x + ', ' + this.y;
}

}

var point = new Point(2, 3);
point.toString() // 2, 3
point.hasOwnProperty('x') // true
point.hasOwnProperty('y') // true

4. 取值函数(getter)和存值函数(setter)

与 ES5 一样,在“类”的内部可以使用get和set关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class MyClass {
constructor() {
// ...
}
get prop() {
return 'getter';
}
set prop(value) {
console.log('setter: '+value);
}
}

let inst = new MyClass();

inst.prop = 123;
// setter: 123

inst.prop
// 'getter'