This article delves into the purpose of the “fat arrow” in CoffeeScript, complemented by examples to illustrate its functionality. The “fat arrow” (=>) in CoffeeScript is a shorthand for defining functions, and it serves a crucial role in handling the this context within functions. The “fat arrow” (=>) in CoffeeScript is a powerful feature for simplifying function syntax and managing the context of this.
Purpose of the “Fat Arrow”
The primary purpose of the “fat arrow” is to lexically bind the this
value. In JavaScript, this
can vary based on the calling context, leading to common pitfalls, especially in callbacks and event handlers. The “fat arrow” in CoffeeScript addresses this issue by ensuring that this
within the function always refers to the context in which the function was defined.
Comparison with regular Arrow (->
)
CoffeeScript also offers the regular arrow (->
) for function definition. The difference lies in how this
is treated:
- Regular Arrow (
->
): Does not bindthis
. Its value is determined by the function’s calling context. - Fat Arrow (
=>
): Lexically bindsthis
to the context where the function is defined.
Examples
To better understand the “fat arrow”, let’s look at some examples.
Example 1: Using =>
in an Object Method
Consider an object with a method that uses a timeout. We want this
to refer to the object itself.
CoffeeScript:
class Greeter
constructor: (name) ->
@name = name
delayedGreet: ->
setTimeout (=> alert "Hello, #{@name}"), 1000
g = new Greeter("Alice")
g.delayedGreet() # Alerts "Hello, Alice" after 1 second
JavaScript Equivalent:
class Greeter {
constructor(name) {
this.name = name;
}
delayedGreet() {
setTimeout(() => {
alert("Hello, " + this.name);
}, 1000);
}
}
var g = new Greeter("Alice");
g.delayedGreet(); // Alerts "Hello, Alice" after 1 second
In this example, the =>
ensures that this.name
within setTimeout
refers to the name
property of the Greeter
instance.
Example 2: Regular arrow vs. fat arrow
Demonstrating the difference in how this
is treated:
CoffeeScript:
class Counter
count: 0
increment: ->
setInterval (=> @count++), 1000
incrementWithoutFatArrow: ->
setInterval (-> @count++), 1000
counter = new Counter()
counter.increment() # `this` is correctly bound, count will increment
counter.incrementWithoutFatArrow() # `this` is not bound, count will not increment
JavaScript equivalent:
class Counter {
constructor() {
this.count = 0;
}
increment() {
setInterval(() => {
this.count++;
}, 1000);
}
incrementWithoutFatArrow() {
setInterval(function() {
this.count++;
}, 1000);
}
}
var counter = new Counter();
counter.increment(); // `this` is correctly bound, count will increment
counter.incrementWithoutFatArrow(); // `this` is not bound, count will not increment
In the increment method, => binds this to the instance of Counter, whereas in incrementWithoutFatArrow, this inside setInterval does not refer to the Counter instance.