代码之家  ›  专栏  ›  技术社区  ›  Keith Bentrup

如何以编程方式替换(包装)新方法中的方法?

  •  2
  • Keith Bentrup  · 技术社区  · 15 年前

    我有几个方法需要以基本相同的方式包装成新方法。我的第一个解决方案不起作用,我明白原因,但我不知道这个问题是否有一个简单的解决方案,或者它是否不能按我想做的方式完成。

    下面是一个例子。我有对象a-c,它有onclick方法。我需要在onclick方法之前执行一些代码。我尝试了以下方法:

    // objects a-c
    a = {onClick : function () { console.log('a'); }};
    b = {onClick : function () { console.log('b'); }};
    c = {onClick : function () { console.log('c'); }};
    
    // first try
    var arr = [a, b, c]
    for (var i = 0; i < arr.length; i++) {
        var oldOnClick = arr[i].onClick;
        arr[i].onClick = function () {
            // new code here
            oldOnClick();
        }  
    }
    
    // outputs 'c'
    // what i want is to maintain a reference to the original method
    // so in this case, execute my new code and output 'a'
    a.onClick();
    

    这不起作用,因为当调用新方法时,OldOnClick将从上一次迭代指向该方法,而不是在分配给该方法时指向该方法。

    我忽略了一个简单的解决方案吗?

    4 回复  |  直到 15 年前
        1
  •  3
  •   Pim Jager    15 年前

    你需要的是结束:

    for(var i=0, l=arr.length; i<l; i++){
     (function(i){
       var oldOnclick = arr[i].onClick; 
       //etc.
     })(i);
    }
    
        2
  •  1
  •   Community CDub    7 年前

    你试过用一些AOP脚本框架吗?

    例如,使用jquery aop插件:

    jQuery.aop.before( {target: String, method: 'replace'}, 
      function(regex, newString) { 
        alert("About to replace string '" + this + "' with '" + newString + 
              "' using regEx '" + regex + "'");
      }
    );
    

    也检查 here .

        3
  •  1
  •   Kevin Montrose    15 年前

    javascript绑定规则非常奇怪。真的,javascript很奇怪。

    我不知道我会叫这个 这个 解决方法,但是通过引入子函数,可以引入另一个绑定,从而解决这个特定的问题。

    您的(修改为快速Y铬黑客)代码变为:

    a = {onClick : function () { alert('a'); }};
    b = {onClick : function () { alert('b'); }};
    c = {onClick : function () { alert('c'); }};
    
    var arr = [a, b, c]
    for (var i = 0; i < arr.length; i++) {
        var oldOnClick = arr[i].onClick;
        arr[i].onClick = bind(oldOnClick);
    }
    
    a.onClick();
    b.onClick();
    c.onClick();
    
    function bind(oldFunc)
    {
        return function () {
            //New Code
            oldFunc();
        }  
    }
    

    上面的代码发出三个警告:a、b、c。任何替换'/new code'的操作都将在正确的时间运行。

        4
  •  0
  •   NickFitz    15 年前
    var a = {onClick : function () { console.log('a'); }};
    var b = {onClick : function () { console.log('b'); }};
    var c = {onClick : function () { console.log('c'); }};
    
    var arr = [a, b, c];
    for (var i = 0; i < arr.length; i++) {
        var oldOnClick = arr[i].onClick;
        arr[i].onClick = wrapHandler(oldOnClick);  
    }
    
    function wrapHandler(handler) {
        return function() {
            console.log("New stuff");
            handler();
        }
    }
    
    a.onClick(); // outputs "New stuff" then "a"
    b.onClick(); // outputs "New stuff" then "b"
    b.onClick(); // outputs "New stuff" then "c"