如果抛开 Javascript 用于模拟 Java 类的复杂语法(如 new、Function Object、函数的 prototype属性等),原型系统可以说很简单:

  • 如果所有对象都有私有字段[[prototype]],就是对象的原型。
  • 读一个属性,如果对象本身没有,则会继续访问对象的原型,直到原型为空或者找到为止。

但在 ES6中,Javascript提供了一系列内置函数,已便更为直接的访问操作原型。

  • Object.create 根据指定的原型创建新对象,原型可以是null;
  • Object.getPrototypeOf 获得一个对象的原型
  • Object.setPrototypeOf 设置一个对象的原型

利用这三个方法,我们可以完全抛开类的思维,利用原型来实现抽象和复用。

  1. var cat = {
  2. say(){ console.log("meow~"); },
  3. jump(){ console.log("jump"); }
  4. }
  5. var tiger = Object.create(cat, {
  6. say:{
  7. writable:true,
  8. configurable:true,
  9. enumerable:true,
  10. value:function(){ console.log("roar!"); }
  11. }
  12. })
  13. var anotherCat = Object.create(cat);
  14. anotherCat.say();
  15. var anotherTiger = Object.create(tiger);
  16. anotherTiger.say();

ES6 中的类

在如何场景下,都推荐使用 ES6 的语法来定义类,而令 function 回归原有的函数语义。

基本用法:

  1. class Rectangle {
  2. constructor(height, width) {
  3. this.height = height;
  4. this.width = width;
  5. }
  6. // Getter
  7. get area() {
  8. return this.calcArea();
  9. }
  10. // Method
  11. calcArea() {
  12. return this.height * this.width;
  13. }
  14. }

继承:

  1. class Animal {
  2. constructor(name) {
  3. this.name = name;
  4. }
  5. speak() {
  6. console.log(this.name + ' makes a noise.');
  7. }
  8. }
  9. class Dog extends Animal {
  10. constructor(name) {
  11. super(name); // call the super class constructor and pass in the name parameter
  12. }
  13. speak() {
  14. console.log(this.name + ' barks.');
  15. }
  16. }
  17. let d = new Dog('Mitzie');
  18. d.speak(); // Mitzie barks.