this in JavaScript doesn’t refer to where a function is defined — it depends entirely on how the function is called, which is exactly why it’s confusing coming from most other languages.
const obj = {
name: 'Widget',
regularMethod() {
console.log(this.name); // 'Widget' - called as obj.regularMethod()
},
arrowMethod: () => {
console.log(this.name); // undefined - arrows don't have their own <code>this</code>,
// they use the ENCLOSING scope's this
},
};
obj.regularMethod();
obj.arrowMethod();
// The classic gotcha: losing <code>this</code> when passing a method as a callback
const fn = obj.regularMethod;
fn(); // <code>this</code> is now undefined (or the global object in non-strict mode)
// Fixes: bind, or wrap in an arrow function
const boundFn = obj.regularMethod.bind(obj);
boundFn(); // 'Widget'
The rule of thumb: regular functions get this from how they’re called (the object before the dot); arrow functions inherit this from their surrounding lexical scope at definition time and never rebind it — which is exactly why arrow functions are the default choice for callbacks inside class methods.