【问题标题】:Javascript: How can I execute code on a function call without overwriting that function?Javascript:如何在不覆盖该函数的情况下在函数调用上执行代码?
【发布时间】:2010-10-27 20:25:16
【问题描述】:

所以,我想在每次调用给定函数时执行一些代码,这可行吗?问题是,我可以覆盖现有函数并添加代码,但这需要我知道该函数的确切内容......想象一下“库”的“插件”,而你想要插件-每次调用此库的特定功能时执行代码,但您不想覆盖原始库内容...希望我足够清楚!

如果可行,有没有办法检索提交给函数的参数?

【问题讨论】:

标签: javascript function call


【解决方案1】:

对我来说,这听起来像是包装函数的工作。

编写一个调用另一个函数的函数,并将您的代码放在该函数的末尾(或任何地方)。然后总是调用你的版本。

一种适配器模式。 http://en.wikipedia.org/wiki/Adapter_pattern

如果您无法修改调用代码,我相信您可以隐藏原始函数的范围并为您的函数命名(不适用于一些内在函数,如警报,但应该适用于库代码)。如果这不是一个选项,请查看原型是否允许您扩展对象以添加功能。 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]);
    }
}

【讨论】:

  • 感谢您的回答!将带我阅读所有这些内容,但是您帖子末尾的论点确实很有用,以前从未使用过;)。我没有得到阵列的东西与我的探针有什么关系?只是一个关于如何使用原型的“演示”?
  • 是的,它是从我在其上方发布的链接中复制的,作为原型演示的一部分;他们正在向 Array 添加切片功能。我不想复制他们的整个代码集,因为它真的很长,但我也不想在这里留下一个没有代码的链接。
【解决方案2】:

这绝对是可行的。 JS 是一种动态语言,因此您可以将存储在对象中的函数与您自己的函数交换。例如:

var fxnToWrap = obj.someFunction;
obj.someFunction = function() {
    console.log("booyah, I'm intercepting every call to obj.someFunction");
    fxnToWrap.apply(obj, arguments);
}

【讨论】:

  • 这正是我想要的!不知道 .apply(),似乎对我很有用,谢谢!
  • 我很确定倒数第二行应该是 fxnToWrap.apply(obj, arguments);因为要应用的第一个 arg 设置函数运行的上下文(即,将分配给它的内容)。通过将其设置为 obj,func 将能够使用它来访问对象的属性和方法。
【解决方案3】:

也许你可以覆盖对函数的引用?例如:

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

【讨论】:

    【解决方案4】:

    已编辑以纠正评论中指出的错误

    这可能会解决您的问题:

    function f() {alert("in f");}
    var saved_f = f;
    var f = function() {
      alert("in f2");
      saved_f();
    }
    f();
    

    【讨论】:

    • saved_f 将指向最后一个 f 定义的函数(导致无限递归)。函数声明是 hoisting 的主题。如果您在 firebug 的控制台上尝试它似乎可以工作,因为 Mozilla 实现定义了一个 Function 语句,并且控制台评估的代码被包装在一个 with 块中。在 fbug 中,尝试将上述代码包装在匿名函数中,例如(function (){})();
    • @CMS 感谢您的更正和指导。我已经编辑考虑到这一点(并在萤火虫外部测试)。
    猜你喜欢
    • 1970-01-01
    • 2011-02-03
    • 1970-01-01
    • 1970-01-01
    • 2013-04-18
    • 1970-01-01
    • 1970-01-01
    • 2012-11-25
    • 1970-01-01
    相关资源
    最近更新 更多