Reputation: 20689
Right now I have an object, such as this Pen.
The prototype of the class contains a series of functions and other properties.
var Pen = function(){
this.inkColor = 'red';
this.write = function(text){
document.write(text);
}
this.refill = function(){
console.log('refilling');
}
this.getInkColor = function(){
return this.inkColor;
}
};
var pen = new Pen();
pen.write(pen.getInkColor() + ': Hello');
Is there away to avoid modifying the Pen class, but change the behavior of every function it has, such as print a log before the actual function call?
this.write = function(text){
// do something first
document.write(text);
}
this.refill = function(){
// do something first
console.log('refilling');
}
this.getInkColor = function(){
// do something first
return this.inkColor;
}
Upvotes: 2
Views: 57
Reputation: 1074276
You can replace the functions with wrappers that call the original and also do something else. For instance:
Object.keys(pen).forEach(name => {
const originalFunction = pen[name];
if (typeof originalFunction === "function") {
pen[name] = function(...args) {
console.log(name, args);
return originalFunction.apply(this, args);
};
}
});
That replaces all functions on pen
(only its own, not ones it inherits) with wrappers that first do a console.log
then call the original.
Live Example:
var Pen = function(){
this.inkColor = 'red';
this.write = function(text){
// used console.log instead of document.write
console.log(text);
}
this.refill = function(){
console.log('refilling');
}
this.getInkColor = function(){
return this.inkColor;
}
};
var pen = new Pen();
Object.keys(pen).forEach(name => {
const originalFunction = pen[name];
if (typeof originalFunction === "function") {
pen[name] = function(...args) {
console.log(name, args);
return originalFunction.apply(this, args);
};
}
});
pen.write(pen.getInkColor() + ': Hello');
You can tweak that to handle functions inherited from the prototype, or inherited only from Pen.prototype
(you don't have anything on Pen.prototype
at present), etc.
Upvotes: 2
Reputation: 2075
You could write a function that returns another function:
function doSomethingFirst(somethingToDoFirstFn, thingToDoAfterFn) {
return function() {
somethingToDoFirstFn.apply(null, arguments);
thingToDoAfterFn.apply(null, arguments);
}
}
var Pen = function(){
// code
this.refill = doSomethingFirst(function(){
console.log('somethingFirst');
}, function() {
console.log('refilling');
})
// code
};
Upvotes: 2
Reputation: 395
You can wrap your pen in a Proxy and define an appropriate handler.
var Pen = function(){
this.inkColor = 'red';
this.write = function(text){
document.write(text);
}
this.refill = function(){
console.log('refilling');
}
this.getInkColor = function(){
return this.inkColor;
}
};
var handler = {
get: function(target, name) {
return name in target ? function (...args) {console.log('Hello World'); return target[name](args)} : undefined;
}
};
var pen = new Pen();
var p = new Proxy(pen, handler);
p.write(p.getInkColor() + ': Hello');
Upvotes: 4