将代码追加到现有函数的末尾
Append code to the end of an existing function
每当函数foo()触发时,我需要触发函数bar()。我无法控制功能 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 ;
}
铌。注意 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*/});
这将在两个函数中为您提供相同的"this"
你可以做这样的事情: 演示。
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
请注意,合并函数尝试将预期的"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
- 如何将函数包装在函数中以避免代码重复
- 从var向代码隐藏函数传递值
- 为函数代码编写测试
- 如何简化jquery动画函数代码
- 用于删除数组中的零的Javascript函数代码
- 使用JavaScript中的高阶函数概念,用Python编写纯函数代码
- JQuery each() 函数代码即使在集合中没有元素时也在运行
- javascript.获取javascript函数位置或获取函数代码
- 部分函数代码是't已执行
- 什么'这是jQuery下面函数代码中的错误
- 为什么新函数(代码)比直接执行相同的代码更快
- 如何使用javascript调用ascx函数代码?DotNetNuke
- JQuery函数代码运行不正常
- Node.JS:MongoDB更新回调返回结果,返回函数代码
- 用nodejs在一定时间后运行函数/代码
- Jquery只处理第一个函数/代码块
- 如何确保我的dom操作函数/代码在dom被渲染后被调用
- 在jQuery中获取现成函数代码下面的元素
- Jquery函数返回的函数代码不是值
- 什么是'$(这个)'包含在下面的javascript函数代码中