我是JS的新手,我遇到过这种情况,我需要确定JS对象中定义的方法是否遵循特定的接口。
让我在一个例子的帮助下解释:
let logger1 = {
log: function(message, meta){
//logging functionality
}
};
let logger2 = {
log: function(level, message, meta){
//logging functionality
}
}
有2个记录器对象(logger1或logger2),它们有自己的记录功能。它们可以从客户端传递到客户端消耗的库。
库期望log方法属于特定的接口,这在库文档中已经提到过。在库内部,我们如何验证传入的记录器对象是否具有与接口匹配的“log”方法,库是否期望?
let Library = function(logger){
//Here I can verify if the 'log' function is defined. But how do i make sure the log
//function matches the interface that the library is expecting ?
//Let's say the interface that the library is expecting is function(level,message,meta),
//which is satisfied only by logger2.
if(logger && typeof(logger.log) === 'function'){
this.logger = logger;
}
else{
this.logger = console;
}
}
let lib1 = new Library(logger1);
let lib2 = new Library(logger2);
答案 0 :(得分:3)
你不能真的。 Javascript函数可以省略它不使用的参数,因此该函数可能具有更少的参数并且仍然兼容。该函数可以定义 more 参数,如果没有传递将成为undefined
,因此仍然是兼容的。它可能在内部使用arguments
,因此没有定义任何参数,仍然兼容。它可以以任何方式命名它的任何参数,并且仍然兼容,因此即使检查参数名称也无济于事。
你唯一可以做的就是使用Typescript之类的东西并添加编译时检查。
答案 1 :(得分:1)
( message, meta )
和logger2 ( message, meta, level )
。
这样我们就可以调用任何一个函数。 ( 'test', 'extra', 1 )
和logger1将忽略level参数。
如果你使用的系统必须兼顾很多不同的论证版本,那么每次只使用一个对象作为唯一的参数可能会更好:function( config )
并且只需在需要时添加额外的属性。
这样你也可以强制界面保持不变,同时也可以某种方式扩展。
答案 2 :(得分:0)
函数有一个属性长度属性,它给出了它拥有的参数数量
示例:
let logger1 = {
log: function(message, meta){
//logging functionality
}
};
console.log(logger1.log.length); // 2
let logger2 = {
log: function(level, message, meta){
//logging functionality
}
}
console.log(logger2.log.length); // 3