ES6 Class 基本语法(上)

Class 的基本语法

类的由来

JavaScript 语言中,生成实例对象的传统方法是通过构造函数。下面是一个例子。

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);

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

ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。

基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。上面的代码用 ES6 的class改写,就是下面这样。

class Point {
 constructor(x, y) {
 this.x = x;
 this.y = y;
 }
 toString() {
 return '(' + this.x + ', ' + this.y + ')';
 }
}

上面代码定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法,而this关键字则代表实例对象。也就是说,ES5 的构造函数Point,对应 ES6 的Point类的构造方法。

Point类除了构造方法,还定义了一个toString方法。注意,定义“类”的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了。另外,方法之间不需要逗号分隔,加了会报错。

ES6 的类,完全可以看作构造函数的另一种写法。

class Point {
 // ...
}
typeof Point // "function"
Point === Point.prototype.constructor // true

上面代码表明,类的数据类型就是函数,类本身就指向构造函数。

使用的时候,也是直接对类使用new命令,跟构造函数的用法完全一致。

class Bar {
 doStuff() {
 console.log('stuff');
 }
}
var b = new Bar();
b.doStuff() // "stuff"

构造函数的prototype属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype属性上面。

class Point {
 constructor() {
 // ...
 }
 toString() {
 // ...
 }
 toValue() {
 // ...
 }
}
// 等同于
Point.prototype = {
 constructor() {},
 toString() {},
 toValue() {},
};

constructor 方法

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

class Point {
}
// 等同于
class Point {
 constructor() {}
}

上面代码中,定义了一个空的类Point,JavaScript 引擎会自动为它添加一个空的constructor方法。

constructor方法默认返回实例对象(即this),完全可以指定返回另外一个对象。

类必须使用new调用,否则会报错。这是它跟普通构造函数的一个主要区别,后者不用new也可以执行。

class Foo {
 constructor() {
 return Object.create(null);
 }
}
Foo()
// TypeError: Class constructor Foo cannot be invoked without 'new'

类的实例

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

class Point {
 // ...
}
// 报错
var point = Point(2, 3);
// 正确
var point = new Point(2, 3);
//定义类
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)
作者:RiemannHypothesis

%s 个评论

要回复文章请先登录注册