The reason is that the definition of Pino
(pino
in the module) does not return an instance of pino
but a synthesised object -- it has a return instance
statement at the end.
Although that returned object has received a specific prototype, it is not pino.prototype
.
So when an instance of Logger
is created, it also returns this "foreign" object while rrr
remains "orphaned" on the unused Logger.prototype
.
See this simplified demo:
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
If pino
would just return a proper instance (this
), then rrr
would be available:
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
Ugly work around
If you really need the extension, then it can be done like this, but it would be better to ask the library author to make their classes extensible:
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