1

假设我正在使用一个库,其代码如下所示:

(function($)
{
    function Library(el, options)
    {
        return new Library.prototype.init(el, options);
    }
    Library.fn = $.Library.prototype = {
        init: function(el, options) {
            this.$elm.on('keydown.library', $.proxy(this.keydown.init, this));
        }
        keydown: function() {
            return {
                init: function(e) {
                    ... somecode
                },
                checkStuff: function(arg1, arg2) {
                    ...someCode
                }
            }
        };
    }
})(jQuery);

它有一个插件系统,可提供对此的访问,其中这是一个Object {init: function, keydown: function...}. 我想覆盖 keydown.init 函数。通常我可以看到使用 _.wrap 之类的东西来做到这一点:

somefunc = _.wrap(somefuc, function(oldfunc, args) {
     donewstuff();
     oldfunc.call(this.args);
});

但这似乎不适用于返回的嵌套方法,例如:

this.keydown.init = _.wrap(this.keydown.init, function(oldfunc, args) {
     donewstuff();
     oldfunc.call(this.args);
});

这个问题可能会在这里得到回答,但我真的不知道用来描述这种编码风格的正确词,所以很难搜索。如果您让我知道将其称为嵌套返回方法是否正确,则可以加分?

4

3 回答 3

2

这种模式称为模块。您可以在这里做的最好的事情是缓存您想要覆盖的方法并在您的覆盖中调用缓存的方法:

somefunc._init = somefunc.init;
somefunc.init = function () {
    doStuff();
    this._init();
};

我检查了 _.wrap 并且它做了同样的事情,正如另一个答案所指出的那样,您缺少的是您正在丢失somefunc. 为了防止你可以这样做:

somefunc.init = _.wrap(_.bind(somefunc.init, somefunc), function (oldRef, args) {
    doStuff();
    oldRef.call(this.args);
});
于 2015-04-20T16:02:28.287 回答
1

问题是您的方法脱离了上下文。

您需要设置其this上下文(用于.bind()

somefunc.init = _.wrap(somefuc.init.bind(somefunc), function(oldfunc, args) {
     donewstuff();
     oldfunc.call(this.args);
});
于 2015-04-20T16:12:56.143 回答
1

您将需要装饰(阅读:包装)该keydown函数,以便您可以包装init它返回的对象的方法:

somefunc.keydown = _.wrap(somefunc.keydown, function(orig) {
    var module = orig(); // it doesn't seem to take arguments or rely on `this` context
    module.init = _.wrap(module.init, function(orig, e) {
         donewstuff();
         return orig.call(this, e);
    });
    return module;
});
于 2015-04-20T17:33:47.397 回答