所以...我一直在编写一个似乎工作正常的包装器(我称其为Medium)。问题是这很丑:
var Medium = function(fn, args){
var __fn = cloneFunction(fn);
var __length = fn.length;
var __args = args.length >= fn.length ? args : fill(fn.length, args);
var __self = this;
this.getFn = function(){ return cloneFunction(__fn) }
this.getLength = function(){ return __length }
this.getArgs = function(){ return clone(__args) }
this.pass = function(sprdArgs){ ... }
this.force = function(sprdArgs){ ... }
this.call = function(sprdArgs){ ... }
this.apply = function(thisArg, sprdArgs){ ... }
this.bind = function(thisArg, sprdArgs){ ... }
this.rewrite = function(fn){ ... }
this.recharge = function(sprdArgs){ ... }
this.clear = function(){ ... }
this.reload = function(args){ ... }
this.use = function(funcName, sprdArgs){ ... }
this.method = function(thisArg, funcName, args){ ... }
}
起初,我将其作为具有一些私有属性,getter和原型的简单构造函数进行构建:
var Medium = function(fn, args){
var __fn = cloneFunction(fn);
var __length = fn.length;
var __args = args.length >= fn.length ? args : fill(fn.length, args);
var __self = this;
this.getFn = function(){ return cloneFunction(__fn) };
...
}
Medium.prototype.pass = function(sprdArgs){
var fnArgs = this.getArgs();
return arguments.length > 0
? this.use("load", arguments)
: this.use("update", fnArgs);
}
...
然后,我认为添加一些对媒体本身可见但对用户不可见的方法会很酷。我还没有找到一个好的解决方案,所以我只是将这些方法移到了一个仅在this
值匹配的情况下才返回被调用函数的方法:
var Medium = function(fn, args){
...
this.method = function(thisArg, funcName, args){
var funcs = {
load: function(args){ ... },
update: function(params){ ... },
execute: function(){ ... }
};
return thisArg === __self
? funcs[funcName].apply(thisArg, args)
: null;
}
}
Medium.prototype.use = function(funcName, sprdArgs){
var args = clone(arguments);
var sprdArgs = filter(args, function(elem, i){
return i !== 0;
});
return this.method(this, funcName, sprdArgs);
}
是的,我还有一个pipe
函数,它使用apply
。结果:我将函数传递给pipe
,而this
的值变为空。 99%的时间都不是什么大问题,但是使用Medium可以简单地破坏所有吸气剂的材料:
function pipe(fns){
var fns = clone(arguments);
return function(vals){
var vals = clone(arguments)
return reduce(fns, function(args, fn, i){
var params = i === 0 ? args : [args];
return fn.apply(null, params);
}, vals);
}
}
为了进行复制,Medium不再使用原型。所有函数都在构造函数中声明。不幸的是,这使它很难阅读-而且我认为这可能会引起其他问题,因为在我对包装器的研究中,通常建议人们在原型上实现行为。
以防万一,我已经对整个过程做了一个JSFiddle。您可以在这里看到它:https://jsfiddle.net/hguerra/0q1urc9o/15/
OBS:您可以看到一些奇怪的功能,例如filter
,reduce
和其他东西。是的,它们是阵列的。我正在使用的JS构建没有任何与数组相关的功能,因此我已尽力使每个人都受感。我可以说的是,它们都按照您对push
和unshift
的预期工作。这两个返回新数组而不是新长度。无论如何,这些功能也很麻烦,因此如果您有任何疑问,可以在此处检查。