我正在现有库的上下文中构建模块。一些库的功能 - 特别是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
语句 - 它只是为了清晰起见而被提升了吗?答案 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);
}
}
}