实际上你已经自己解决了这个问题,至少几乎是:
这适用于做任何事情的任何数量的功能。我正在考虑切换plugin.has()
到 doplugin.has("afk","check");
或类似的东西,所以不是链接函数,它只是在一个函数中。但是将变量传递给检查函数会变得很棘手。
好吧,基本上有两种方法:
plugin_with_afk.has("afk","check").check(100); // "check" twice
plugin_with_afk.has("afk","check")(100); // "check" not twice
第一种方法实际上相当简单:this
如果插件有“afk”则简单地返回,否则返回一个具有无操作方法的对象check
:
Plugin.prototype.has = function(str, member){
if(this.things.indexOf(str) > -1) {
return this;
} else {
var tmp = {}
tmp[member] = function(){}
return tmp;
}
}
plugin_with_afk.has("afk","check").check(1); // has afk, check is there
plugin_without_afk.has("afk","check").check(2); // has no afk, check is no-op
plugin_without_afk.has("nope","check").check(3); // has nope, check is there
这还有一个很大的优势,即您不需要使用任何函数包装器等。ReferenceError
但是,您必须指定使用的函数两次,如果您不小心使用了另一个名称,这将导致:
plugin_with_afk.has("afk","check").test(1); // oh oh
那么你能做些什么呢?创建一个简单的函数包装器:
PluginWithFuncRet.prototype.has = function(str,member){
var self = this;
if(this.things.indexOf(str) > -1) {
return function(){
return self[member].apply(self, arguments);
}
} else {
return function(){};
}
}
plugin_with_afk.has("afk","check")(4); // calls check()
plugin_without_afk.has("afk","check")(5);// no-op
就是这样。请注意,您实际上应该重命名has
为use_if
或类似的东西,因为它现在做的事情比实际检查组件是否存在更多。
var PluginBase = function(name, things){
this.name = name;
this.things = things;
}
/// First variant
var Plugin = function() {
this.constructor.apply(this, arguments);
}
Plugin.prototype.constructor = PluginBase;
Plugin.prototype.has = function(str,member){
if(this.things.indexOf(str) > -1) {
return this;
} else {
var tmp = {}
tmp[member] = function(){}
return tmp;
}
}
var plugin_with_afk = new Plugin("with afk", ["afk"]);
plugin_with_afk.check = function(val){
console.log("hi", val, this.name);
};
var plugin_without_afk = new Plugin("w/o afk", ["nope"]);
plugin_without_afk.check = function(val){
console.log("nope", val, this.name);
}
/// First variant demo
plugin_with_afk.has("afk","check").check(1)
plugin_without_afk.has("afk","check").check(2)
plugin_without_afk.has("nope","check").check(3)
/// Alternative
var PluginWithFuncRet = function(){
this.constructor.apply(this, arguments);
}
PluginWithFuncRet.prototype.constructor = PluginBase;
PluginWithFuncRet.prototype.has = function(str,member){
var self = this;
if(this.things.indexOf(str) > -1) {
return function(){
return self[member].apply(self,arguments);
}
} else {
return function(){}
}
}
plugin_with_afk = new PluginWithFuncRet("with afk",["afk"]);
plugin_with_afk.check = function(val){
console.log("Hi",val,this.name);
}
plugin_without_afk = new PluginWithFuncRet("w/o afk",["nope"]);
plugin_without_afk.check = function(val){
console.log("Nope",val,this.name);
}
/// Alternative demo
plugin_with_afk.has("afk","check")(4);
plugin_without_afk.has("afk","check")(5);
plugin_without_afk.has("nope","check")(6);
结果:
嗨 1 与 afk
不 3 w/o afk
嗨 4 与 afk
不 6 w/o afk