Pages

Wednesday, October 12, 2011

Rationale for CoffeeScript's 'Fat Arrow' syntax

I gave a CoffeeScript presentation last night at our local Groovy Users of Minnesota meet up. One of the questions that came up last night had to do with CoffeeScript's fat arrow (=>) syntax, which will both define a new function and bind the new function to the current value of this. This is super helpful for callback-based libraries, such as jQuery.

I was building a Backbone.View today (in JavaScript) and had to deal with this binding. In my JavaScript, I wanted to call fadeOut on the view's el property (which happens to be a jQuery wrapped element). Without using the jQuery proxy method to bind this appropriately, my statement of 'this.el.fadeOut();' will not work. The this reference is no longer the view at the point I'm using it in the anonymous function; the context for this has changed within the anonymous function declaration. The correct JavaScript code is below.


var MyView = Backbone.View.extend({

initialize: function() {
this.template = _.template($('#my-template').html(), this.model.toJSON());
this.render();
},

render: function() {
this.el.html(this.template);
return this;
},

events: {
"click button#doSomethingButton": "doSomething",
},

doSomething: function(e) {
this.model.set({someValue: $('#someValueTextField').val()});
var promise = this.model.doSomethingOnModel();
promise.done($.proxy(function() {
this.el.fadeOut();
}, this)
).fail(function() {
alert('Failed to check sequence uniqueness.');
});
}
});


So how does this relate to CoffeeScript? Well, the fat arrow operator is performing the proxying of the 'this' reference for you. If I wrote the above in CoffeeScript, I could write the done callback as:



promise.done => @el.fadeOut()



Chaining the done and the fail callbacks would necessitate the use of parentheses, but still very succinct. Score one for CoffeeScript!

2 comments: