0

我正在现有库的上下文中构建一个模块。库的一些功能——具体来说,LIBRARY.module.add例如:实际功能要复杂得多)——可以在各种场景中触发,会破坏我模块的用户体验,所以我需要中断它以考虑我的模块的深奥问题。

我不允许重新编写原始库的任何部分,也不允许复制应该由库覆盖的功能。

现有代码是这样的:

LIBRARY.moduleX = {
    two      : 2,
    addToTwo : function(addAnd){
        return this.two + addAnd;
    }
}

这里的一个关键问题是LIBRARY模块都是用文字对象表示法编写的,并且它们的方法依赖于this. 另一个问题是代码库不断变化。我不能依赖addToTwo's arity 或类似的东西(以防有人扩展它以获取多个操作数或其他)。

所以我写了这个来作为我组件初始化的一部分执行:

void function handleModuleX(){
    // Keep a reference before rebinding
    var LIBRARY_moduleX_addToTwo = LIBRARY.moduleX.addToTwo;

    // Restores the original binding
    function rebind(){
        LIBRARY.moduleX.addToTwo = function(){
            return LIBRARY_moduleX_addToTwo.apply(LIBRARY.moduleX, arguments);
        }
    }

    // Rebind to consider local logic
    LIBRARY.moduleX.addToTwo = function handleEsotericLogic(){
        if(unresolvedConcerns){
            stuff();
        }
        else {
            rebind();

            LIBRARY.moduleX.addToTwo();
        }
    }
}();

这似乎有效。我最关心的是重新绑定的安全性和易读性:

  • 这种技术是防弹的,因为它不做任何假设addToTwo吗?
  • 这是否尽可能接近恢复原始绑定?
  • 我可以在不嵌套这么多范围的情况下实现相同的功能吗(显然rebind可以写入else语句中——它只是为了清楚起见才被吊出)?
4

1 回答 1

0

更多的研究使我找到了 underscore 的bind方法,它与我对 polyfill ECMAScript 5的同名本机 Function 方法所做的基本相同——这似乎是我可以避免上述实现中涉及的 2 个闭包的唯一方法. 所以现在我的代码更冗长了——因为我真的不喜欢调用库方法的想法,如果可能的话,会在堆栈跟踪上的代码中反弹(就像我从未接触过它一样!):

function rebind(){
    if(Function.prototype.bind){
        LIBRARY.moduleX.addToTwo = LIBRARY_moduleX_addToTwo.bind(LIBRARY.moduleX);
    }
    else {
        LIBRARY.moduleX.addToTwo = function(){
            return LIBRARY_moduleX_addToTwo.apply(LIBRARY.moduleX, arguments);
        }
    }
}
于 2013-03-20T14:58:49.600 回答