我正在现有库的上下文中构建一个模块。库的一些功能——具体来说,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
语句中——它只是为了清楚起见才被吊出)?