我想弄清楚如何扩展:
var outdatedBrowser = function(options) {
function startStylesAndEvents() {
console.log("bleh");
}
}
我试图覆盖函数startStylesAndEvents而不触及库的源代码:https://github.com/burocratik/outdated-browser/blob/develop/outdatedbrowser/outdatedbrowser.js
所以当我打电话时:
outdatedBrowser({
bgColor: '#f25648',
color: '#ffffff',
lowerThan: 'transform',
languagePath: 'your_path/outdatedbrowser/lang/en.html'
})
它使用startStylesAndEvents函数,它使用我的而不是他们的......
谢谢!
答案 0 :(得分:2)
不修改原始来源?你不能。
所有JavaScript范围都基于函数(暂时忽略let
,const
和class
。如果在函数内部声明了一个值,则除非从函数返回或修改某个外部值,否则不能在该函数外部访问它。
例如,想象一下这样的函数:
function doStuff() {
var times = 10;
for (var i = 0; i < times; i++) {
doThing(i);
}
}
您的问题在语义上与询问如何更改times
相同。它无法完成。
答案 1 :(得分:2)
内部函数包含在一个您无权访问的闭包中。不幸的是(与“没有不可能的”意识形态相反),这不能在运行时完成。
答案 2 :(得分:0)
这就是你所谓的'私人'功能。该函数与任何其他变量一样存储。在JavaScript中,通常意味着它必须是“本地范围”(而不是成员变量),因此无法覆盖它。 (如果他们只使用过this.functionName
...那么你可以更轻松地覆盖)
好消息是,有一个似乎是跨浏览器兼容的黑客。 (在IE 11中测试,仿真选项返回到IE 5!)在JavaScript中,您可以替换函数本身的实际“源代码”。 (与正确的覆盖略有不同)
var newInnerFunction = function () { // intentionally anonymous for use in eval
}
var overriddenFunction = eval(
outdatedBrowser.toString() // expecting outdatedBrowser to be anonymous for use in eval
.replace('{', '{var startStylesAndEvents=' + newInnerFunction.toString() + ';')
)
请注意,outdatedBrowser
是一个匿名函数(只是function()
)。如果它被命名,则使用eval
会产生将新函数添加到其原始名称下的命名空间的副作用。如果这是一个问题,额外的replace
可以解决这个问题。
答案 3 :(得分:0)
最有可能的是,你不能。但这并非完全不可能。
例如,如果在范围对象泄露到外部的startStylesAndEvents
语句中调用with
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"
当然不要这样做。它是邪恶的,缓慢的,不允许在严格的模式下。