我需要触发函数bar()每当函数foo()火灾。 我有超过函数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 ;
}
}
例如:
appendToFunction(foo,"bar();");
这在我看来是一个可怕的想法 - 但它的作品。 有人能指出我在一个更好的(更安全)的方向吧。
编辑: foo
不是一个特定的功能,但很多功能,我清盘处理。 他们没有在页面动态变化。 但是,他们可能会改变(例如,表单验证需求)不时。
解决方案 :我对亚当的回答修改后的版本解决。 它并不完美,但它是比我有更好的:
var oldFoo = foo ;
foo = function(){
var result = oldFoo.apply(this, arguments);
bar();
return result ;
}
NB。 当心在IE6 / 7一些本地函数没有一个.apply()
方法。
你可以只覆盖foo
与调用原始的自定义功能。
如
var old_foo = foo;
foo = function() {
old_foo();
bar();
}
你也应该传递任何参数foo
通过您的替换功能考虑到它。
function extend(fn,code){
return function(){
fn.apply(fn,arguments)
code.apply(fn,argumnets)
}
}
并使用它像这样:
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*/});
这会给你“这”两个功能相同
你可以做这样的事情: 演示 。
function foo() {
console.log('foo');
}
function appendToFunction(fn, callback) {
window[fn] = (function(fn){
return function() {
fn();
callback();
}
}(window[fn]));
}
appendToFunction('foo', function(){console.log('appended!')});
foo();
嗯,这涉及我也,你提到
我经常有这种情况(我恨它)。
你介意我在什么情况下该保持发生问吗? 它是在企业规模,还是在个人项目的范围有多大? 你已经清楚地得到了一个水平头你的肩膀,并知道你在做什么是不寻常的,所以我不知道如果有一个交替的解决方案。
我想问的原因是, 这种做法可能会打开的问题即可。 如果foo
例如失败,或者如果foo
返回一个值中期评估? 通过简单的附加bar
,以实际功能并不保证它会执行。 预未决它在另一方面意味着它更容易执行,但仍然在我看来,是不是一个好方法。
你有没有考虑修订功能foo
? 我知道,这似乎是一个愚蠢的问题,但如果你遇到类似的整个问题,它可能是值得的。 如果你想保持抽象的东西,你可以采取“事件处理”的方式,因此foo
触发一个事件window
,这反过来然后触发bar
,你的情况,将这项工作。
或者,如果你知道foo
是,和它做什么,你可以挂接到它的原型,如果它是一个对象,然后适当地修改代码出现。 但是你没有提到这个功能是开放的变化,这可能使该选项多余的,但它是一个可能的解决方案仍然。
您可以追加或预先准备一些新的代码,以现有的功能,只使用例如合并它们:
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);
}
}
一个基本的例子是以下几点:
// 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
需要注意的是合并函数试图预期“这个”适用于合并后的部分,否则,你可以只是简单的传递希望“这个”给他们,以及你可以处理的相对参数。
一个更普遍的例子可能是以下几点:
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