gotchajavascriptMajor
'this' binding lost in callbacks and event handlers
Viewed 0 times
this bindinglost contextarrow functionbindcallback this
Error Messages
Problem
When passing a method as a callback, 'this' becomes undefined (strict mode) or the global object. obj.method works, but setTimeout(obj.method, 100) loses the 'this' context.
Solution
Three fixes:
// 1. Arrow function (most common)
setTimeout(() => obj.method(), 100);
button.addEventListener('click', () => this.handleClick());
// 2. bind()
setTimeout(obj.method.bind(obj), 100);
// 3. In classes, use arrow function properties
class MyComponent {
handleClick = () => {
console.log(this); // always the instance
};
}
// 4. In React class components
constructor() {
this.handleClick = this.handleClick.bind(this);
}
// 1. Arrow function (most common)
setTimeout(() => obj.method(), 100);
button.addEventListener('click', () => this.handleClick());
// 2. bind()
setTimeout(obj.method.bind(obj), 100);
// 3. In classes, use arrow function properties
class MyComponent {
handleClick = () => {
console.log(this); // always the instance
};
}
// 4. In React class components
constructor() {
this.handleClick = this.handleClick.bind(this);
}
Why
In JavaScript, 'this' is determined by HOW a function is called, not where it's defined. When you pass obj.method as a callback, you're passing the function reference without the object context. Arrow functions capture 'this' from the enclosing scope.
Gotchas
- Arrow functions cannot be used as constructors (no new keyword)
- bind() creates a new function — calling it multiple times creates multiple copies
- In DOM event handlers, 'this' refers to the element unless you use arrow functions
- Arrow class properties create a new function per instance — not on the prototype
Code Snippets
Preserving this in callbacks
class Timer {
count = 0;
// BAD: 'this' lost in setTimeout
start() {
setInterval(function() {
this.count++; // TypeError!
}, 1000);
}
// GOOD: arrow function preserves 'this'
start() {
setInterval(() => {
this.count++; // works!
}, 1000);
}
}Context
When passing methods as callbacks to setTimeout, event listeners, or array methods
Revisions (0)
No revisions yet.