Методы расширенного класса не предоставляются

1

Я пытаюсь расширить класс в 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

Спасибо,

  • 0
    Не могу воспроизвести. jsfiddle.net/x3gse5ja Опубликуйте код Pino, если вы хотите, чтобы его можно было отлаживать.
  • 0
    Пожалуйста, отправьте код Pino . Может быть, он возвращает простой объект, а не правильный экземпляр? Вы можете проверить, есть ли pp instanceof Logger (возможно, false ) и есть ли pp instanceof Pino .
Показать ещё 8 комментариев
Теги:
class
ecmascript-6

2 ответа

1
Лучший ответ

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

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

Поэтому, когда создается экземпляр Logger, он также возвращает этот "чужой" объект, в то время как rrr остается " Logger.prototype " в неиспользованном 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
  • 0
    Привет trincot, не могли бы вы объяснить больше об этом или указать мне, чтобы alink или что-нибудь Если возможно, я могу знать, чтобы расширить этот модуль каким-либо другим способом?
  • 1
    Даже если бы это был pino.prototype (который помог бы с instanceof pino ), это не позволило бы расширить «класс».
Показать ещё 4 комментария
0

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

Функция, возвращаемая функцией require('pino') является фабричной функцией, а не функцией конструктора. Таким образом, синтаксис class сахар не будет работать для настройки прототипа 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 и объектные прототипы - это большая углубленная книга на эту тему.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню