simple's Studio.

ES5中JavaScript的类

2017/11/03

#####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!
CATALOG