Reputation: 21914
Here is a simple decorator pattern which modifies a normal function:
function decorator1(f){
function wrapper(...args){
pre();
return f(...args);
post();
}
return wrapper
}
Now assume there is an object obj
and it has a property prop
in its prototype. I want to modify the object's bound function for some reason.
I can't use this pattern directly to decorate the bound function obj.prop
because if I pass it as an argument to the decorator
, it won't get invoked with the correct object in the wrapper
because JavaScript relies on the calling to pass the correct object. So obj.prop()
is context-aware but obj.prop
is not. Is there a way to overcome this limitation?
If that is not possible I need to either:
Change the pattern to accept the object and property as 2 different arguments and make it work.
function decorator2(o, f){
function wrapper(...args){
pre();
return o.f(...args);
post();
}
return wrapper
}
obj.prop = decorator2(obj, prop);
Pass a bound function which for some reason I think is a hard-coding.
// This creates a bound function to itself.
obj.prop = obj.prop.bind(obj)
// This modifies it.
obj.prop = decorator1(obj.prop)
Which one is preferred? I would go for the former because I think that creating bound functions are not good unless you really need them.
Upvotes: 1
Views: 1751
Reputation: 664297
You can just use this
in the wrapper
:
function decorate(f) {
return function wrapper(...args) {
pre();
const res = f.apply(this, args); // or f.call(this, ...args)
// ^^^^
post();
return res; // make post() work
};
}
With this, a plain obj.prop = decorate(obj.prop);
will work.
Upvotes: 3