Методы расширенного класса не предоставляются - PullRequest
0 голосов
/ 12 января 2019

Я пытаюсь расширить класс в javascript и добавить некоторые дополнительные функции к этому классу.

const Pino = require('pino');

class Logger extends Pino {
  constructor(options = { name: 'isWorking' }) {
    super(options);
    this.check = "1234";
    this.ppp = () => {}
  }

  rrr() {}
}

let pp = new Logger();
console.log(pp.check)
console.log(pp.ppp)
console.log(pp.rrr)
console.log(pp instanceof Logger)
console.log(pp instanceof Pino)

Это вывод

1234
[Function]
undefined
false
false

Почему эта функция rrr не доступна? я думал о переопределении базового класса. Это должно работать для нормального класса, что особенного в этом Pino классе?

Примечание: здесь базовый класс pino - это модуль javascript

Спасибо

Ответы [ 2 ]

0 голосов
/ 12 января 2019

Примечание: я сопровождающий Пино.

Функция, возвращаемая require('pino'), является фабричной функцией , а не функцией конструктора. Таким образом, синтаксис class sugar не будет работать для настройки прототипа Pino: мы не выставляем прототип.

Чтобы настроить Pino, нужно обернуть экземпляр своей функциональностью:

const instance = require('pino')()
Object.defineProperties(instance, {
  rrr: {
    value: function () {
      this.info('this is the rrr function')
    }
  }
})

instance.rrr()

Я настоятельно рекомендую узнать, как на самом деле работают объекты в Javascript, вместо того чтобы полагаться на (на мой взгляд, катастрофический) синтаксис class. Два столпа Javascript - превосходный набор статей на эту тему. И Вы не знаете, JS: this и прототипы объектов - это большая углубленная книга по этому вопросу.

0 голосов
/ 12 января 2019

Причина в том, что определение Pino (pino в модуле) возвращает не экземпляр pino, а синтезированный объект - в конце он имеет оператор return instance.

Хотя этот возвращенный объект получил конкретный прототип, он не является pino.prototype.

Таким образом, когда создается экземпляр Logger, он также возвращает этот «чужой» объект, в то время как rrr остается «осиротевшим» на неиспользованном Logger.prototype.

См. Это упрощенное демо:

function Pino() { return new Date(); }

class Logger extends Pino {
    rrr() { return 1; }
}

const a = new Pino;
const b = new Logger;

console.log(a instanceof Pino); // false
console.log(b instanceof Logger); // false
console.log(b instanceof Pino); // false
console.log(b instanceof Date); // true

console.log(typeof b.rrr); // undefined

Если pino просто вернет правильный экземпляр (this), тогда будет доступно rrr:

function Pino() {  } // returns `this`

class Logger extends Pino {
    rrr() { return 1; }
}

const a = new Pino;
const b = new Logger;

console.log(a instanceof Pino); // true
console.log(b instanceof Logger); // true
console.log(b instanceof Pino); // true
console.log(b instanceof Date); // false (obviously)

console.log(typeof b.rrr); // function

Уродливая работа вокруг

Если вам действительно нужно расширение, то это можно сделать следующим образом, но лучше попросить автора библиотеки сделать их классы расширяемыми:

function Pino() { return new Date(); }

function PinoClass() {} // Don't define anything in this class
PinoClass.prototype = Object.getPrototypeOf(new Pino);

class Logger extends PinoClass {
    rrr() { return 1; }
}

const a = new Pino;
const b = new Logger;

console.log(a instanceof Pino); // false
console.log(b instanceof Logger); // true
console.log(b instanceof Pino); // false
console.log(b instanceof Date); // true

console.log(typeof b.rrr); // function
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...