暂时重新绑定然后安全地重新附加库方法

时间:2013-03-20 12:44:37

标签: javascript functional-programming this dynamic-rebinding

我正在现有库的上下文中构建模块。一些库的功能 - 特别是LIBRARY.module.add为了示例:实际功能更精细) - 可以在各种场景中触发,将破坏我的模块的用户体验,所以我需要打断它,以考虑我的模块的深奥问题。

我不允许重写原始库的任何部分,并且我不允许复制该库所涵盖的功能。

现有代码如下:

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

这里的一个关键问题是LIBRARY的模块都是用文字对象表示法编写的,它们的方法依赖于this。另一个问题是代码库不断变化。我不能依赖addToTwo的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语句 - 它只是为了清晰起见而被提升了吗?

1 个答案:

答案 0 :(得分:0)

更多的研究引导我强调bind方法,这与我填充ECMAScript 5的同名本机函数方法基本相同 - 这似乎是唯一的方法我可以避免上面实现中涉及的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);
        }
    }
}