This sort of thing happens a lot when people learn jQuery but not Javascript. This fascinating "jQuery feature" is just a wrapper for JavaScript's built-in functions call and/or it's brother apply.<p><a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/call" rel="nofollow">https://developer.mozilla.org/en/JavaScript/Reference/Global...</a><p><a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply" rel="nofollow">https://developer.mozilla.org/en/JavaScript/Reference/Global...</a>
Since the app is apparently written using backbone.js, the _.bindAll method would be a neater solution here (as I see one of the commenters on the post points out).
I prefer to just use a closure - but that just might be because I've used them so long that my brain thinks it looks nicer.<p>Another nice context-setting trick is to set the context manually when you do ajax requests - then callbacks will have the context of the object you did the request in:<p><pre><code> var myobj = {
done: "I'm done.",
load: function(){
$.ajax({
context: this,
success: function(){
alert(this.done);
}
});
}
};</code></pre>
I don't know when jQuery added this method, but for the longest time they didn't have it and made you use closures even while most other javascript libraries had similar methods. Their argument was that you should know what's going on rather than just using a convenience method all over the place (and likely in situations where you don't need it).
That looks like a Class in MooTools. Difference seems to be that it is a single lib dependency and "proxy" is called "bind"<p>It would look something like this<p><pre><code> var FBNotificationWatcher = new Class({
Implements: [Options],
options: {
timeout: 500,
url: 'http://dot.com',
onRequestComplete: function(response){}
},
initialize: function(options){
this.setOptions(options);
this.request = new Request({
url: this.options.url,
onComplete: function(resp){
this.processNotifications(resp);
this.options.onRequestComplete(resp);
}.bind(this)
});
this.getNotifications();
},
getNotifications: function(){
this.request.send({//data});
return this;
},
processNotifications: function(rawNotificationData){
//do stuff
this.getNotifications.delay(this.options.timeout, this);
}
});
</code></pre>
I'll check out backbone if I'm doing some jQuery dev.
I guess this is kind of surprising/interesting if you haven't taken a functional programming course in university, but as others have pointed out, proxy is just a simpler wrapper on top of 'apply'/'call'. You should read the docs on those two functions, as the difference in the way they work is subtle but worth understanding.
IIRC, .bind(this) was used in the exact same way in mootools years and years ago, and maybe even in Prototype before that.<p>Oh how I wish mootools had won the JS library war...
Nice technique but it definitely illustrates the problems which Javascript's ill-defined this-keyword brings about (which was discussed here a few days ago).<p>This same problem could easily have been solved by setting a private variable (self, _this, cx, whatever) to this upon instantiation and referring to that instead of this.<p>In fact, I find myself using that technique (using self-defined variables instead of context) , especially for namespacing.<p><pre><code> var myNamespace = {};
(function(cx) {
cx.myClass = function() {
var self = this;
self.action = function() {
self.foo = "bar";
}
};
})(myNamespace);
</code></pre>
It makes your code easier to refactor with fewer hard-references to maintain. I'm about to completely give up any usage of "this" for a "var self = this;" upon object-creation.<p>Javascript context-handling is really just too messed up to be dependent on, and while it allows for lots of "cute" hacks, I personally find it creating a lot more problems than it solves.