Javascript 当这个值很重要时,pipable包装器的最佳设计模式
所以。。。我一直在编写一个包装器(我称之为Medium),它似乎工作得很好。问题是它非常丑陋:Javascript 当这个值很重要时,pipable包装器的最佳设计模式,javascript,design-patterns,this,wrapper,pipeline,Javascript,Design Patterns,This,Wrapper,Pipeline,所以。。。我一直在编写一个包装器(我称之为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;
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);
}
...
然后我认为添加一些对媒体本身可见但对用户不可见的方法会很酷。我还没有找到一个好的解决方案,所以我只是将此方法移动到一个getter,该getter仅在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);
}
问题是,我还有一个管道
函数,它使用应用
。结果:我将函数传递给我的管道
,而此
值变为空。99%的时间里都没什么大不了的,但如果是中号的话,它只会破坏所有的getter元素:
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);
}
}
为了重新制作,媒体不再使用原型。所有函数都在构造函数中声明。不幸的是,这使得它很难阅读——我认为这可能会导致其他问题,因为在我所做的关于包装器的研究中,人们通常建议在原型上实现行为
以防万一,我把整件事都弄混了。你可以在这里看到:
OBS:您可以看到一些奇怪的函数,如
过滤器
,减少
等等。是的,它们是阵列的。我正在使用的JS的构建没有任何与数组相关的函数,因此我已经更好地对它们进行了轮询。就我所能说的而言,它们的工作方式与您期望的push
和unshift
一样;这两个函数返回新数组,而不是新长度。不管怎样,这些函数也很有用,所以如果您有任何疑问,可以在那里查看 我真的不明白你想做什么。如果需要私有方法,只需在构造函数中定义它们,而不必依赖于此。如果你的pipe
方法是导致nullI出现问题的原因,那么你可能应该提供它,但它已经在处理中了,而且它在项目的其余部分工作得很好——换句话说,我并不认为pipe
是问题所在。(但可以肯定的是)关于我的目标是什么。。。我看中号的,很难看。我觉得这并不是解决这个问题的最佳方案,部分原因是我在网上看到的大多数包装器在原型上都有自己的方法。换句话说,我只想知道是否有一条更好的路径,如果是的话,那是哪条路径。只要把\fn
、\u length
和\u args
作为实例和原型上所有方法的属性,每个人都是这样做的。这不是有点粗心吗?我觉得放弃这些变量的隐私可能会破坏我的代码。我说错了吗?