Why does 'this' behave differently in regular functions vs arrow functions in JavaScript?

I’m trying to understand why the this keyword works in regular functions but not in arrow functions. I have two similar pieces of code and only one works correctly.

When I use a regular function, this refers to the object as expected. But when I switch to an arrow function, this doesn’t work the same way. Can someone explain what’s happening here?

checkSkill: function() {
    let response = prompt("Do you know coding? (yes/no): ");
    if (response === 'yes') {
        console.log(`${this.username} knows coding.`);
    }
    else {
        console.log(`${this.username} doesn't know coding.`);
    }
}

checkSkill: () => {
    let response = prompt("Do you know coding? (yes/no): ");
    if (response === 'yes') {
        console.log(`${this.username} knows coding.`);
    }
    else {
        console.log(`${this.username} doesn't know coding.`);
    }
}

What makes these two approaches behave differently when it comes to this binding?

Regular functions change their this based on who calls them, but arrow functions lock onto the this from where they’re created. When you write an arrow function inside an object literal, it doesn’t grab the object’s context - it captures whatever this was in the surrounding scope (usually the global object or undefined in strict mode). That’s why your first example works - the regular function gets called on the object, so this points to it. The arrow function ignores who’s calling it and sticks with whatever this it inherited.

totally agree! arrow funcs don’t have their own this, they just take it from the outer context. that’s why your regular function behaves as expected while the arrow one doesn’t. it’s all about how they bind this!

The difference is how they handle this binding. Regular functions bind this dynamically based on how you call them - so when used as object methods, this points to the object. Arrow functions don’t work this way. They inherit this from wherever they’re defined, not where they’re called. Your arrow function is probably grabbing this from the global scope instead of your object, making this.username undefined. That’s why you shouldn’t use arrow functions for object methods when you need access to the object’s properties.