每次调用对象中的任何函数时都运行一个函数

Run a function every time any function in object is called

本文关键字:函数 运行 一个 对象 调用 任何      更新时间:2023-09-26

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

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

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

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值,并将参数作为其第二个参数的集合传递。

它还返回从函数返回的任何内容的值。

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'});

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

没有简单的方法可以做到这一点。如果你已经编写了所有"原始"方法并且知道回调的叫法,你可以按照 Felix 在注释中提到的操作,遍历对象上的每个属性,如果它是一个函数,则将其重新赋值为调用回调的新函数:

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();
        }
    }
}

已编辑以将key()更改为obj[key]()