【问题标题】:How can I replace (wrap) methods in new methods programmatically?如何以编程方式替换(包装)新方法中的方法?
【发布时间】:2010-11-04 15:20:54
【问题描述】:

我有几个方法需要以基本相同的方式封装在新方法中。我的第一个解决方案不起作用,我明白为什么,但我不知道是否有一个简单的解决方案可以解决这个问题,或者是否无法按照我想要的方式完成。

这是一个例子。我有具有 onClick 方法的对象 a-c。我需要在 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 将指向上一次迭代的方法,而不是分配时的 to 方法。

有没有我忽略的简单解决方案?

【问题讨论】:

    标签: javascript methods scope variable-assignment


    【解决方案1】:

    你需要的是闭包:

    for(var i=0, l=arr.length; i<l; i++){
     (function(i){
       var oldOnclick = arr[i].onClick; 
       //etc.
     })(i);
    }
    

    【讨论】:

    • ahh .. 是的 b/c 将立即执行。 thx,我认为有一个简单的解决方案。 :)
    【解决方案2】:

    您是否尝试过一些用于 Javascript 的 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】:

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

      我不知道我会调用这种 方法来修复它,但是通过引入一个子函数,您可以引入另一个绑定,从而解决这个特定问题。

      您的(已针对快速 Chrome 黑客修改)代码变为:

      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】:
        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"
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-04-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-13
          • 1970-01-01
          • 2022-11-19
          • 1970-01-01
          相关资源
          最近更新 更多