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"