#####ES5 “类”总结
因为 ES6 类只是一个“幻景”(语法糖),原型继承实际上在底层被隐藏起来了,我们快速了解下如何用 ES5 代码创建“类”:
function Plane(numEngines) {
this.numEngines = numEngines;
this.enginesActive = false;
}
// methods "inherited" by all instances
Plane.prototype.startEngines = function () {
console.log('starting engines...');
this.enginesActive = true;
};
const richardsPlane = new Plane(1);
richardsPlane.startEngines();
const jamesPlane = new Plane(4);
jamesPlane.startEngines();
在上述代码中,Plane 函数是一个构造函数,它将用来创建新的 Plane 对象。具体的 Plane 对象的数据被传递给 Plane 函数,并设置到该对象上。每个 Plane 对象继承的方法被放置在 Plane.prototype 对象上。然后,richardsPlane 被创建后有一个引擎,而 jamesPlane 被创建后有四个引擎。但是,这两个对象都使用相同的 startEngines 方法来激活各自的引擎。
需要注意的事项:
- 构造函数使用 new 关键字被调用
- 按照惯例,构造函数名以大写字母开头
- 构造函数控制将被创建的对象的数据的设置
- “继承”的方法被放在构造函数的原型对象上
当我们了解 ES6 类的原理时,请记住这几点,因为 ES6 类都在底层帮你设置了所有这些。
#####ES6 类
以下是同一 Plane 类使用新的 class 语法编写后的代码:
class Plane {
constructor(numEngines) {
this.numEngines = numEngines;
this.enginesActive = false;
}
startEngines() {
console.log(‘starting engines…’);
this.enginesActive = true;
}
}
###类只是一种函数
为了证明类没有任何特别之处,我们来看看下面的代码:
class Plane {
constructor(numEngines) {
this.numEngines = numEngines;
this.enginesActive = false;
}
startEngines() {
console.log('starting engines…');
this.enginesActive = true;
}
}
typeof Plane; // function
Returns: function
没错,它只是个函数!甚至没有向 JavaScript 添加新类型。
⚠️ 逗号都去哪了? ⚠️
你是否注意到,类中的方法定义之间没有任何逗号了?在类中,不用逗号来区分属性或方法。如果添加逗号,将出现 SyntaxError:unexpected token
###静态方法
要添加静态方法,请在方法名称前面加上关键字 static。请看看下面的代码中的 badWeather() 方法。
class Plane {
constructor(numEngines) {
this.numEngines = numEngines;
this.enginesActive = false;
}
static badWeather(planes) {
for (plane of planes) {
plane.enginesActive = false;
}
}
startEngines() {
console.log('starting engines…');
this.enginesActive = true;
}
}
注意 badWeather() 在前面有单词 static,而 startEngines() 没有?这样使得 badWeather() 成为 Plane 类中可以直接访问的方法,因此你可以这样调用它:
Plane.badWeather([plane1, plane2, plane3]);
注意:对构造函数、类方法或原型继承的原理有点困惑?我们专门开设了一门课程。请参阅面向对象的 JavaScript。
###类的优势
- 设置内容更少
- 创建函数要编写的代码少多了
- 清晰地定义了构造函数
- 在类定义总,可以清晰地指定构造函数。
- 全部都包含起来了
- 类需要的所有代码都包含在类声明中。你可以同时设定一切内容,而不用在一个位置编写构造函数,然后向原型一个一个地添加方法,你可以同时做所有的事!
#####使用类时需要注意的事项 - class 不是魔术
- 关键字 class 带来了其它基于类的语言中的很多思想观念。它没有像变魔术一样向 JavaScript 类添加了此功能。
- class 是原型继承的抽象形式
我们已经多次提到,JavaScript 类实际上使用的就是原型继承。
使用类需要用到 new
在创建 JavaScript 类的新实例时,必须使用关键字 new
例如
class Toy {
...
}
const myToy1 = Toy(); // throws an error
Uncaught TypeError: Class constructor Toy cannot be invoked without 'new'
但是,添加关键字 new 后问题就解决了
const myToy2 = new Toy(); // this works!