Javascript 覆盖函数中的函数
我正试图找出如何扩展:Javascript 覆盖函数中的函数,javascript,extend,Javascript,Extend,我正试图找出如何扩展: var outdatedBrowser = function(options) { function startStylesAndEvents() { console.log("bleh"); } } 我试图在不接触库源代码的情况下覆盖函数startStylesAndEvents: 所以当我打电话时: outdatedBrowser({ bgColor: '#f25648', color: '#ffffff', lowerThan:
var outdatedBrowser = function(options) {
function startStylesAndEvents() {
console.log("bleh");
}
}
我试图在不接触库源代码的情况下覆盖函数startStylesAndEvents:
所以当我打电话时:
outdatedBrowser({
bgColor: '#f25648',
color: '#ffffff',
lowerThan: 'transform',
languagePath: 'your_path/outdatedbrowser/lang/en.html'
})
它使用startStylesAndEvents函数,它使用我的而不是他们的
谢谢 而不修改原始源?你不能 所有JavaScript作用域都基于函数(暂时忽略
let
、const
和class
)。如果某个值是在函数内部声明的,则不能在该函数外部访问该值,除非该值是从函数返回的或修改了某些外部值
例如,想象这样一个函数:
function doStuff() {
var times = 10;
for (var i = 0; i < times; i++) {
doThing(i);
}
}
函数doStuff(){
风险价值倍数=10;
对于(变量i=0;i<次;i++){
doThing(i);
}
}
您的问题在语义上与询问如何更改时间相同。它就是做不到。内部函数包含在一个闭包中,您无权访问该闭包。不幸的是(与“没有什么是不可能的”思想相反),这不能在运行时完成。这就是您可以称之为“私有”函数的功能。该函数与任何其他变量一样存储。在JavaScript中,这通常意味着它必须是“局部范围”(而不是成员变量),因此不能被重写。(如果他们使用了
this.functionName
,那么您就可以更容易地重写它了)
好消息是,有一个黑客似乎是跨浏览器兼容的。(在IE11中测试,模拟选项回到IE5!)在JavaScript中,您可以替换函数本身的实际“源代码”。(与正确的超控有点不同)
请注意,
outdatedBrowser
是一个匿名函数(只需function()
)。如果它被命名,那么使用eval
会产生副作用,将新函数以其原始名称添加到名称空间中。如果这是一个问题,一个额外的替换可以解决它。很可能,你不能。但这并非完全不可能
例如,如果在范围对象已泄漏到外部的with
语句中调用startStylesAndEvents
var scope = Object.create(null);
var outdatedBrowser = function(options) {
function startStylesAndEvents() {
console.log("bleh");
}
with(scope) {
startStylesAndEvents(); // You expect this to be the private function above
}
}
outdatedBrowser(); // "bleh"
然后,您可以劫持对startStylesAndEvents
的调用:
scope.startStylesAndEvents = function() {
console.log("blah");
};
outdatedBrowser(); // "blah"
当然,不要这样做。这是邪恶的、缓慢的,并且在严格模式下是不允许的。不幸的是,这需要“接触库的源代码”,这在OP中是行不通的。@GeorgeBailey不一定。问题并不是说库如何调用函数。如果库在语句中调用该函数,而该语句的作用域对象已泄漏到外部,则无需修改库。极不可能,但并非不可能。我认为OP是在避免改变outdatedBrowser
@MikeC我不是说OP应该改变outdatedBrowser
。OP显然跳过了一些代码(否则更改startStylesAndEvents
没有意义,因为它不是在outdatedBrowser
内部调用的)。我只是说,如果调用在with
语句中,那么你可以劫持startStylesAndEvents
而不改变过期浏览器
@Oriol他们跳过了一些代码以避免在这里发布所有内容。
scope.startStylesAndEvents = function() {
console.log("blah");
};
outdatedBrowser(); // "blah"