当此值重要时,可浸式包装纸的最佳设计模式

时间:2018-07-23 11:51:46

标签: 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;

    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:您可以看到一些奇怪的功能,例如filterreduce和其他东西。是的,它们是阵列的。我正在使用的JS构建没有任何与数组相关的功能,因此我已尽力使每个人都受感。我可以说的是,它们都按照您对pushunshift的预期工作。这两个返回新数组而不是新长度。无论如何,这些功能也很麻烦,因此如果您有任何疑问,可以在此处检查。

0 个答案:

没有答案