我希望每次调用任何其他函数时都调用函数X.我希望尽可能保持通用。
有这两个功能
function x(){ console.log("invoke BEFORE"); }
function someFunction(something){ console.log(something); }
调用someFunction
时
someFunction("testoutput");
我希望控制台输出:
>> invoke BEFORE
>> testoutput
我还希望将此行为应用于某个对象的任何函数。
例如:
var myFunctions = {
first:function(){/* do something */},
second:function(){/* do something else*/}
}
myFunctions.before(function(){/ 在 /}之前做一些事情);
任何人都知道解决方案吗?
编辑:
我想出了这样的解决方案:
Object.prototype.before = function(x){
for(var key in this){
if(typeof this[key] === "function")
this[key] = (function(x, f) {
var g = f;
return (function() {
x();
return g.apply(this, arguments);
});
}(x, this[key]));
}
}
var test = { func: function(){console.log("test")}};
test.before(function(){console.log("before")});
test();
结果:
>> before
>> test
YAAAYYY
你怎么喜欢这个?答案 0 :(得分:1)
这是一个糟糕的主意,可以更加难以理解和调试您的程序。
您可以使用Python中称为“猴子修补”的内容来实现此目的:
(function() {
{
var origSomeFunction = someFunction;
someFunction = (function() {
x();
return origSomeFunction.apply(this, arguments);
});
}();
这是有效的,因为我更改了(全局)名称someFunction
以引用我定义的新函数。在该函数的闭包内,我保留了对要传递调用的原始函数的引用。
答案 1 :(得分:0)
在我看来,事件绑定比函数包装更灵活,因为您可以随时删除// Observable
var Observable = {};
Observable.create = function (options) {
var observable = { events: {} };
var events = options.events || [];
var i, l = events.length;
for (i = 0; i < l; i++) {
observable.events[events[i]] = [];
}
return observable;
};
Observable.one = function (observable, event, handler) {
Observable.on(observable, event, function f () {
Observable.un(observable, event, f);
handler.apply(this, arguments);
});
};
Observable.on = function (observable, event, handler) {
observable.events[event].push(handler);
};
Observable.un = function (observable, event, handler) {
observable.events[event].splice(
observable.events[event].indexOf(handler), 1
);
};
Observable.emit = function (observable, event, params) {
var handlers = observable.events[event];
var i, l = handlers.length;
if (!params) params = {};
params.source = observable;
for (i = 0; i < l; i++) {
handlers[i].call(observable, params);
}
};
Observable.observeMethod = function (observable, name) {
var meth = observable[name];
var before = 'before' + name.toLowerCase();
var after = 'after' + name.toLowerCase();
observable.events[before] = [];
observable.events[after] = [];
observable[name] = function () {
var ret;
Observable.emit(observable, before);
ret = meth.apply(observable, arguments);
Observable.emit(observable, after, { value: ret });
return ret;
};
};
// init
var printer = init({
sayHello: function () {
this.print('Hello World.');
},
sayHi: function (e) {
this.print('Hi ' + e.pseudo + '.');
},
print: function (msg) {
print(msg);
}
});
var clock = init({
tid: null,
events: ['tick'],
stop: function () {
clearTimeout(this.tid);
},
start: function () {
var me = this;
var time = 0;
clearTimeout(this.tid);
(function tick () {
me.tid = setTimeout(tick, 1000);
me.emit('tick', { time: time++ });
})();
}
});
// demo: printer
printer.on('afterprint', printNewline);
printer.on('beforesayhello', printBullet);
printer.sayHello();
printer.sayHello();
printer.un('beforesayhello', printBullet);
printer.sayHello();
// demo: clock
clock.on('tick', function (e) {
if (e.time) printer.print('tick ' + e.time);
if (e.time === 3) this.stop();
});
clock.one('afterstop', clock.start);
clock.start();
// helpers
function init (obj) {
obj = initObservable(obj);
obj.one = function (event, handler) {
Observable.one(this, event, handler);
};
obj.on = function (event, handler) {
Observable.on(this, event, handler);
};
obj.un = function (event, handler) {
Observable.un(this, event, handler);
};
obj.emit = function (event, params) {
Observable.emit(this, event, params);
};
return obj;
}
function initObservable (obj) {
var k, observable;
observable = Observable.create({
events: obj.events
});
for (k in observable) {
obj[k] = observable[k];
}
for (k in obj) {
if (typeof obj[k] === 'function') {
Observable.observeMethod(obj, k);
}
}
return obj;
}
function printBullet () {
print('• ');
}
function printNewline () {
print('<br />');
}
function print (html) {
document.body.innerHTML += html;
}
。这是一个可能的实现:
onPushReceive