我正在尝试使用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 :(得分:2)
注意:我是Pino的维护者。
require('pino')
返回的函数是http://review.romancecapsule.com,而不是“构造函数”函数。因此,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
语法。 factory function是关于该主题的出色文章集。 The Two Pillars of Javascript是一本关于该主题的深入书籍。
答案 1 :(得分:1)
原因是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