Javascript:如何在函数调用中执行代码而不覆盖该函数?
所以,我想每次调用某个函数都要执行一些代码,这是可行的吗?事情是,我可以覆盖现有的函数并添加代码,但这需要我知道该函数的确切内容......想象一下“库”的“插件”,并且想要插件,在每次执行代码时都会调用这个图书馆的特定功能,但是你不想覆盖原来的图书馆内容......希望我已经清楚了!Javascript:如何在函数调用中执行代码而不覆盖该函数?
如果它是可行的,有没有办法检索提交给函数的参数?
这绝对是可行的。 JS是一种动态语言,因此您可以使用自己的函数交换存储在对象中的函数。例如:
var fxnToWrap = obj.someFunction;
obj.someFunction = function() {
console.log("booyah, I'm intercepting every call to obj.someFunction");
fxnToWrap.apply(obj, arguments);
}
这就是我一直在寻找的!不知道.apply(),似乎对我非常有用,谢谢! – Alex 2010-10-27 21:01:04
我很确定倒数第二行应该是fxnToWrap.apply(obj,arguments);因为要应用的第一个参数设置函数运行的上下文(即将分配给它的内容)。通过将其设置为obj,func将能够使用它来访问该对象的属性和方法。 – 2010-10-27 23:43:28
@Sid_M你是对的!固定。 – kevingessner 2010-10-28 01:25:25
可能你可以覆盖对函数的引用?例如:
function add1(x) { return x + 1; }
function log_calls(f, name) {
return function() {
console.log("got a call to", name, "with args", arguments);
return f.apply(null, arguments);
}
}
add1 = log_calls(add1, "add1");
然后调用add1
会是这样的:
>> x = add1(42)
"got call to add1 with args [42]"
>> x
43
请问我需要什么,谢谢。 – Alex 2010-10-27 21:01:56
听起来像一个工作,一个包装函数给我。
编写一个调用其他函数的函数,并将你的代码放在那个(或任何地方)的末尾。然后总是调用你的版本。
适配器模式的排序。 http://en.wikipedia.org/wiki/Adapter_pattern
我相信你可以隐藏原始函数的作用域,并且如果你不能修改调用代码(不适用于像alert这样的一些内在函数,但应该适用于库代码),那么你的名字也是一样的。如果这不是一个选项,请参阅原型是否允许您扩展对象以添加功能。 http://phrogz.net/js/classes/ExtendingJavaScriptObjectsAndClasses.html
//Only add this implementation if one does not already exist.
if (Array.prototype.slice==null) Array.prototype.slice=function(start,end){
if (start<0) start=this.length+start; //'this' refers to the object to which the prototype is applied
if (end==null) end=this.length;
else if (end<0) end=this.length+end;
var newArray=[];
for (var ct=0,i=start;i<end;i++) newArray[ct++]=this[i];
return newArray;
}
对于参数,你也可以让你的版本采取可选的参数(类似的jQuery/MooTools的),然后看看发生了什么过去了。
此处可选参数的示例。 http://www.openjs.com/articles/optional_function_arguments.php
function accident() {
for(var i = 0; i < arguments.length; i++) {
alert("This accident was caused by " + arguments[i]);
}
}
编辑以纠正错误的评论
指出,这可能会解决你的问题:
function f() {alert("in f");}
var saved_f = f;
var f = function() {
alert("in f2");
saved_f();
}
f();
'saved_f'将指向最后一个'f'定义的函数(导致无限递归)。函数声明是[提升]的主题(http://stackoverflow.com/questions/1710424/referencing-a-javascript-value-before-it-is-declared-can-someone-explain-this/1710509#1710509)。如果你在Firebug的控制台上尝试它,似乎可以工作,因为Mozilla实现定义了一个Function语句,并且控制台评估的代码被封装在一个'with'块中。在fbug中,尝试使用匿名函数来封装上述代码,例如'(function(){})();' – CMS 2010-10-27 20:47:57
@CMS感谢您的纠正和指导。我已经编辑了这个考虑(并在萤火虫外测试)。 – 2010-10-27 23:52:31
在[面向方面](http://en.wikipedia.org/wiki/Aspect-oriented_programming)和[功能](http://en.wikipedia.org/wiki/Functional_programming)编程,你问的是[[建议]](http://en.wikipedia.org/wiki/Advice_%28programming%29)。 – outis 2010-10-28 00:06:05