javascript 将代码附加到现有函数的末尾
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11222618/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Append code to the end of an existing function
提问by ColBeseder
I need to trigger function bar() whenever function foo() fires. I have no control over function foo or whether it will change in the future. I have this situation regularly (and I hate it).
每当函数 foo() 触发时,我都需要触发函数 bar()。我无法控制函数 foo 或者它将来是否会改变。我经常遇到这种情况(我讨厌它)。
I wrote this function to add my code to the end of function foo:
我编写了这个函数来将我的代码添加到函数 foo 的末尾:
function appendToFunction(fn,code){
if(typeof fn == 'function'){
var fnCode = fn.toString() ;
fnCode = fnCode.replace(/\}$/,code+"\n}") ;
window.eval(fnCode); // Global scope
return true ;
}
else{
return false ;
}
}
eg:
例如:
appendToFunction(foo,"bar();");
This strikes me as a terrible idea - but it works. Can somebody point me in a better (safer) direction please.
这让我觉得是一个糟糕的主意——但它确实有效。有人可以指出我更好(更安全)的方向吗?
EDIT: foo
is not a specific function, but many functions that I wind up dealing with. They don't change dynamically in the page. But they may be changed (eg. form validation demands) from time to time.
编辑:foo
不是一个特定的功能,而是我最终处理的许多功能。它们不会在页面中动态更改。但它们可能会不时更改(例如表单验证要求)。
Solution: I settled on a modified version of Adam's Answer. It's not perfect, but it's better than what I had:
解决方案:我选择了 Adam's Answer 的修改版本。它并不完美,但比我拥有的要好:
var oldFoo = foo ;
foo = function(){
var result = oldFoo.apply(this, arguments);
bar();
return result ;
}
NB. Watch out for some native functions in IE6/7 that don't have an .apply()
method.
注意。注意 IE6/7 中一些没有.apply()
方法的本机函数。
回答by Adam Heath
You can just override foo
with a custom function that calls the original.
您可以foo
使用调用原始函数的自定义函数进行覆盖。
E.g.
例如
var old_foo = foo;
foo = function() {
old_foo();
bar();
}
You should also pass any arguments foo
takes into it via your replacement function.
您还应该foo
通过替换函数将任何参数传递给它。
回答by cuzzea
function extend(fn,code){
return function(){
fn.apply(fn,arguments)
code.apply(fn,argumnets)
}
}
and use it like this:
并像这样使用它:
function appendToFunction(fn,code){
if(typeof fn == 'function'){
var fnCode = fn.toString() ;
fnCode = fnCode.replace(/\}$/,code+"\n}") ;
window.eval(fnCode); // Global scope
return true ;
}
else{
return false ;
}
}
appendToFunction = extend(appendToFunction,function(){/*some code*/});
this will give you the same "this" in both functions
这将在两个函数中为您提供相同的“this”
回答by xdazz
回答by Richard
Hmm, this concerns me as well, you mentioned that
嗯,这也是我关心的,你提到过
I have this situation regularly (and I hate it).
我经常遇到这种情况(我讨厌它)。
Do you mind if I ask in what scenario this keeps occurring? Is it in a corporate scale, or on a personal project scope? You've clearly got a level head on your shoulders and know that what you're doing is out of the ordinary, so I'm wondering if there is an alternatively solution.
你介意我问一下在什么情况下这种情况会持续发生吗?是在公司范围内,还是在个人项目范围内?您显然已经冷静下来,并且知道您所做的事情与众不同,所以我想知道是否有替代解决方案。
The reason I ask is; this approach could potentially open a can of problems. What if foo
fails for example, or if foo
returns a value mid evaluation? By simply appending bar
to the actual function doesn't guarantee it will execute. Pre-pending it on the other hand means it's morelikely to be executed, but still in my opinion isn't a good approach.
我问的原因是;这种方法可能会带来一系列问题。foo
例如,如果失败,或者如果foo
在评估中返回值怎么办?通过简单地附加bar
到实际函数并不能保证它会执行。另一方面,预先挂起它意味着它更有可能被执行,但在我看来仍然不是一个好方法。
Have you considered revising the function foo
? I know this might seem like a silly question, but it might be worth it if you're encountering similar problems throughout. If you want to keep things abstracted you could adopt an "event handler" approach, whereby foo
triggers an event on the window
, which in turn then triggers bar
, would this work in your case.
您是否考虑过修改功能foo
?我知道这似乎是一个愚蠢的问题,但如果您在整个过程中遇到类似的问题,这可能是值得的。如果您想保持抽象,您可以采用“事件处理程序”方法,从而在 上foo
触发一个事件window
,然后触发bar
,这是否适用于您的情况。
Alternatively, if you know what foo
is, and what it does, you could hook into it's prototype if it's an object, and then amend the code there appropriately. You did however mention that this function is open to change, which may make this option redundant, but it's a possible solution nonetheless.
或者,如果您知道是什么foo
以及它做什么,如果它是一个对象,您可以挂钩它的原型,然后适当地修改那里的代码。然而,您确实提到此功能可以更改,这可能会使此选项变得多余,但它仍然是一个可能的解决方案。
回答by Luca Borrione
You can append or prepend some new code to an existing function just mergingthem using for example:
您可以将一些新代码附加或添加到现有函数中,只需使用以下示例合并它们:
function mergeFunctions(function1, function2, instance1, instance2, numberOfArgumentsToPassToFunc1) {
return function() {
var _arguments = Array.prototype.slice.apply(arguments);
var _arguments1 = _arguments.slice(0, numberOfArgumentsToPassToFunc1);
var _arguments2 = _arguments.slice(numberOfArgumentsToPassToFunc1);
var that = this;
(function(function1, function2) {
if (typeof function1 == "function") {
if (typeof instance1 != "undefined") {
function1.apply(instance1, _arguments1);
}
else if (that == window) {
function1.apply(function1, _arguments1);
}
else {
var compare = mergeFunctions(function(){}, function(){});
if (that.toString() == compare.toString()) {
function1.apply(function1, _arguments1);
}
else {
function1.apply(that, _arguments1);
}
}
}
if (typeof function2 == "function") {
if (typeof instance2 != "undefined") {
function2.apply(instance2, _arguments2);
}
else if (that == window) {
function2.apply(function2, _arguments2);
}
else {
var compare = mergeFunctions(function(){}, function(){});
if (that.toString() == compare.toString()) {
function2.apply(function2, _arguments2);
}
else {
function2.apply(that, _arguments2);
}
}
}
})(function1, function2);
}
}
A basic examplewould be the following:
一个基本的例子如下:
// Original function:
var someFunction = function(){
console.log("original content");
};
// Prepend new code:
// --------------------------------------------------------
someFunction = mergeFunctions(function() {
console.log("--- prepended code");
}, someFunction);
// Testing:
someFunction();
// Outout:
// [Log] --- prepended code
// [Log] original content
// Append new code:
// --------------------------------------------------------
someFunction = mergeFunctions(someFunction, function() {
console.log("appended code");
});
// Testing:
someFunction();
// Output:
// [Log] --- prepended code
// [Log] original content
// [Log] appended code
Notethat the merging function tries to apply the expected 'this' to the merged parts, otherwise you can just simply pass the wanted 'this' to them, as well as you can handle the relative arguments.
A more general examplecould be the following:
请注意,合并函数尝试将预期的“this”应用于合并的部分,否则您只需将想要的“this”传递给它们,并且您可以处理相关参数。
一个更一般的例子可能如下:
function firstPart(a, b) {
console.log("--- first part");
console.log("'this' here is:");
console.log(this.name);
console.log("a: "+a);
console.log("b: "+b);
}
function MyObject() {
this.x = "x property of MyObject";
}
MyObject.prototype.secondPart = function (y) {
console.log("");
console.log("--- second part");
console.log("'this' here is:");
console.log(this.name);
this.x = y;
console.log("x: "+this.x);
}
MyObject.prototype.merged = mergeFunctions(firstPart, MyObject.prototype.secondPart, firstPart, MyObject, 2);
// Testing
var test = new MyObject();
test.merged("a parameter", "b parameter", "x parameter overrides x property of MyObject");
// Console output:
// [Log] --- first part
// [Log] 'this' here is:
// [Log] firstPart
// [Log] a: a parameter
// [Log] b: b parameter
// [Log]
// [Log] --- second part
// [Log] 'this' here is:
// [Log] MyObject
// [Log] x: x parameter overrides x property of MyObject