CoffeeScript Fat vs Thin Arrow: Diagnosing `this` Binding
A diagnostic guide for CoffeeScript `=>` vs `->` `this` binding mismatches. Learn to recognize when a callback loses its instance context, how to check arrow usage, and when to use fat arrows, bind, or closures.
10 Apr 2026, 20:29 UTC

Recognizable condition: `this` is incorrect inside
A callback or event handler references `this` expecting the enclosing class or object, but at runtime `this` is `window`, `undefined`, or the DOM element that fired the event. The CoffeeScript source uses a thin arrow `->` where a fat arrow `=>` is needed.
The useful takeaway is simple: thin arrow compiles to a normal JavaScript function with dynamic `this`. Fat arrow compiles to a function bound to the lexical `this` at definition time. Choose the arrow to match how you need `this` to be resolved.
Cause / diagnostic table
| Symptom | Typical cause | Arrow involved |
|---|---|---|
| `this` is `window` or `undefined` in a plain callback | Function passed as callback, `this` not preserved | Thin arrow `->` with dynamic binding |
| `this` is the event element | Function registered as DOM event listener | Thin arrow `->` receives call-site `this` |
| `this` correctly refers to class instance | Lexical binding used | Fat arrow `=>` |
Ordered checks
- Locate the definition. Find the function using `->` or `=>`. In class syntax this is often `@method: ->` or `@method: =>`. In object literals look for `key: ->`.
- Check for `this` usage inside. If the body references `@property` or `this`, the binding matters. No `this` usage means the arrow choice is usually irrelevant.
- Determine how the function is used. Is it passed as an argument, assigned to a variable, or used as an event listener?
- If binding issue persists, suspect prototype manipulation, `call`/`apply` overrides, or framework-specific binding (e.g., React class components).
Fixes tied to findings
Replace `->` with `=>` at the definition site to bind `this` lexically. If the function must remain a plain function (e.g., for `arguments` access), use `self = this` or `.bind(this)` at the call site. Change `@method: ->` to `@method: =>`.
# Example fix
class Counter
constructor = =
@count = 0
increment = => ->
@count += 1
Verification
Compile a minimal CoffeeScript snippet with both types and inspect the generated JavaScript to confirm `this` behavior. Run the code in a browser or Node.js with a test case that logs `this` inside the callback to observe the difference.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.