I'm having troubling understanding the point of the variable tmp in the following code:
$.extend($.Widget.prototype, {
yield: null,
returnValues: { },
before: function(method, f) {
var original = this[method];
this[method] = function() {
f.apply(this, arguments);
return original.apply(this, arguments);
};
},
after: function(method, f) {
var original = this[method];
this[method] = function() {
this.returnValues[method] = original.apply(this, arguments);
return f.apply(this, arguments);
}
},
around: function(method, f) {
var original = this[method];
this[method] = function() {
var tmp = this.yield;
this.yield = original;
var ret = f.apply(this, arguments);
this.yield = tmp;
return ret;
}
}
});
Why not simply using a function-local variable var yield and completely leaving out tmp in around method? What purpose does it serve? Is this a common design pattern?
Thanks for some hint.
Apparently that code comes from Extending jQuery UI Widgets, which provides some useful context. That article refers to Avoiding Bloat in Widgets as the source for the code. However, the original doesn't have the
tmpvariable.I like the addition of
tmp, because it avoids a side-effect that the original code has. Consider how the around function is supposed to be used:This will work as expected with or without the
tmpjuggling. Theclickevent will now execute your extra code before and after the event.But if you don't restore
yieldusingtmp, the object's public methodyieldwill now be redefined. So if someone would have the strange idea of just callingYourWidgetObject.yield()after usingaround, it would execute whatever existing methodaroundhas last been applied to (in this case,click).Added after request for clarification:
Imagine that you don't restore
yieldat all, nor set it to null. And after the code above, you do this:yieldnow executes the click function on focus, which is very unexpected behavior.Could you just set
yieldto null instead of restoring it withtmp? Sure, as it is now, it won't make a difference. But as you might change or add other methods, it's more prudent to make thearoundmethod unaware of the current state, i.e. it shouldn't have to know thatyieldis always null when it gets called.As a sidenote, I think this is a terrible
aroundmethod, since putting things around an event is not necessarily what it does - you can callyieldhowever many times you want, or not at all. More sensible for a realaroundmethod would be to accept two callbacks, one to be executed before the event and one after. That way you don't need to expose ayieldmethod in the first place.