构造器

  • 9.1 总是使用 class。避免直接操作 prototype

    为什么? 因为 class 语法更为简洁更易读。

    ```javascript
    // bad
    function Queue(contents = []) {
    this._queue = […contents];
    }
    Queue.prototype.pop = function() {
    const value = this._queue[0];
    this._queue.splice(0, 1);
    return value;
    }

  1. // good
  2. class Queue {
  3. constructor(contents = []) {
  4. this._queue = [...contents];
  5. }
  6. pop() {
  7. const value = this._queue[0];
  8. this._queue.splice(0, 1);
  9. return value;
  10. }
  11. }
  12. ```
  • 9.2 使用 extends 继承。

    为什么?因为 extends 是一个内建的原型继承方法并且不会破坏 instanceof

    1. // bad
    2. const inherits = require('inherits');
    3. function PeekableQueue(contents) {
    4. Queue.apply(this, contents);
    5. }
    6. inherits(PeekableQueue, Queue);
    7. PeekableQueue.prototype.peek = function() {
    8. return this._queue[0];
    9. }
    10. // good
    11. class PeekableQueue extends Queue {
    12. peek() {
    13. return this._queue[0];
    14. }
    15. }
  • 9.3 方法可以返回 this 来帮助链式调用。

    1. // bad
    2. Jedi.prototype.jump = function() {
    3. this.jumping = true;
    4. return true;
    5. };
    6. Jedi.prototype.setHeight = function(height) {
    7. this.height = height;
    8. };
    9. const luke = new Jedi();
    10. luke.jump(); // => true
    11. luke.setHeight(20); // => undefined
    12. // good
    13. class Jedi {
    14. jump() {
    15. this.jumping = true;
    16. return this;
    17. }
    18. setHeight(height) {
    19. this.height = height;
    20. return this;
    21. }
    22. }
    23. const luke = new Jedi();
    24. luke.jump()
    25. .setHeight(20);
  • 9.4 可以写一个自定义的 toString() 方法,但要确保它能正常运行并且不会引起副作用。

    1. class Jedi {
    2. constructor(options = {}) {
    3. this.name = options.name || 'no name';
    4. }
    5. getName() {
    6. return this.name;
    7. }
    8. toString() {
    9. return `Jedi - ${this.getName()}`;
    10. }
    11. }