【问题标题】:Run a function every time any function in object is called [duplicate]每次调用对象中的任何函数时运行一个函数[重复]
【发布时间】:2013-06-05 04:26:20
【问题描述】:

如果我有一个看起来像这样的对象:

var animal = { 
    cat: function() { alert('woof'); },
    dog: function() { alert('meow'); }
}

如何将另一个函数“附加”到animal,以便在调用animal 对象中的任何函数时运行它? (无需在每个例程中手动调用它)

【问题讨论】:

  • 您现在唯一能做的就是遍历每个函数属性并将它们包装在一个新函数中,该函数也调用另一个函数。对于未来,ES6 定义了“代理对象”,你也许可以使用......有一天。 (wiki.ecmascript.org/doku.php?id=harmony:proxies)。

标签: javascript


【解决方案1】:
for (var p in animal) {
    if (typeof animal[p] === "function") {
        animal[p] = make(animal[p]);
    }
}

function make(fn) {
    return function() {
        console.log("this is called for every animal");
        // call the original
        return fn.apply(this, arguments);
    }
}

make() 函数接受一个函数参数,并返回一个新函数。

新函数做任何你想做的事情(在这种情况下它只是调用console.log()),然后它调用原始函数。

当它调用原始值时,它设置this 的当前值并传递arguments。它通过使用Function.prototype.apply 调用函数来做到这一点,该函数从其第一个参数设置this 值,并将参数作为其第二个参数的集合传递。

它还返回从您的函数返回的值。

【讨论】:

    【解决方案2】:

    http://jsfiddle.net/TUNQn/

    var EntriesRegistry = (function(){
    
        var instance = null;
    
        function __constructor() {
    
            var
                self = this,
                observations = {};
    
            this.set = function(n,v)
            {
                self[n] = v;
    
                if( observations[n] )
                    for( var i=0; i < observations[n].length; i++ )
                        observations[n][i].apply(null, [v, n]);
    
            }
    
            this.get = function(n)
            {
                return self[n];
            }
    
            this.observe = function(n,f)
            {
    
                if(observations[n] == undefined)
                    observations[n] = [];
    
                observations[n].push(f);
            }
    
        }
    
        return new function(){
            this.getInstance = function(){
                if (instance == null)
                {
                    instance = new __constructor();
                    instance.constructor = null;
                }
                return instance;
            }
        }
    })();
    
    var entries = EntriesRegistry.getInstance();
    
    var test = function(v){ console.log(entries); };
    var name = function(person){
        alert("Hello " + person.first + " " + person.last);
    }
    
    /*entries.set('bob', 'meh');
    
    entries.get('bob');*/
    
    entries.observe('employer', name);
    entries.observe('seth', test);
    
    entries.set('seth', 'lo');
    entries.set('employers', {first: 'test', last: 'test'});
    

    这允许您将回调绑定到对象事件更改

    【讨论】:

      【解决方案3】:

      没有简单的方法可以做到这一点。如果您已经编写了所有“原始”方法并且知道回调被称为什么,那么您可以执行 Felix 在 cmets 中提到的操作并遍历对象上的每个属性,如果它是一个函数,则将其重新分配为一个新函数也调用了回调:

      for (key in obj) {
      
          if (typeof(key) === 'function') {
              obj[key] = function() {
                  obj[key](); //I think this is closed over, didn't test though (might get clobbered)
                  callback();
              }
          }
      }
      

      EDITEDkey() 更改为obj[key]()

      【讨论】:

      • key 是属性的 name 和字符串。你不能调用它。
      • key 是一个字符串,而不是一个方法。
      • 是的,你没有测试它。而key 是一个字符串。而且你没有传递任何论据。而且你没有返回任何东西。
      猜你喜欢
      • 2023-03-27
      • 2012-10-15
      • 2022-06-12
      • 2018-10-28
      • 1970-01-01
      • 1970-01-01
      • 2015-12-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多