When I was first learning JavaScript in Turing's Mod 1, I felt like I was making real progress. I could write loops. I could use conditionals. I was wrapping my head around functions, arrays, and objects. Then came testing — and everything started to fall apart.
When this Broke Everything
We were using Mocha and Chai to test our vanilla JavaScript code, and suddenly I was running into errors I didn’t understand. A method would fail, the test would break, and I’d stare at the screen thinking, "Why doesn’t this work"?
The answer — almost every time — was this.
At the time, I didn’t truly understand what this meant. I assumed it referred to “whatever object I’m working in.” But this isn’t about where code is written — it’s about how the function is called. And this coding world of callbacks, nested functions, and object method references, that distinction mattered. A lot.
What I didn’t realize back then is that this in JavaScript is a trickster. It changes based on:
- The calling context
- Whether you're using arrow functions or regular ones
- Whether something is bound, called, or passed around
Without a strong mental model for how this works, my code started to feel like guesswork. I wasn’t debugging — I was just rearranging pieces and throwing code harder and harder at the wall, hoping something would finally stick.
A Classic Example
One of my first “what is even happening” moments in JavaScript was running into this classic this issue in a test.
function User(name) {
this.name = name;
}
User.prototype.greet = function () {
return `Hello, my name is ${this.name}`;
};
module.exports = User;// user-test.js
const chai = require('chai');
const expect = chai.expect;
const User = require('./user');
describe('User', function () {
const greet = new User('Beth').greet; // ❌ `this` loses context!
it('should return a proper greeting', function () {
expect(greet()).to.equal('Hello, my name is Beth');
// 💥 TypeError: Cannot read properties of undefined (reading 'name')
});
});What Was Actually Happening?
this is no longer bound to the instance of User when we extract the method — so this.name becomes undefined.
Instead of extracting the method, I needed to call the method on the instance of User.
describe('User', function () {
const beth = new User('Beth');
it('should return a proper greeting', function () {
expect(beth.greet()).to.equal('Hello, my name is Beth');
});
});Looking back now, I realize I wasn’t struggling with logic. I was struggling with context. And understanding context — especially how it affects this — changed everything about my writing and understanding JavaScript code.
If you're just starting out and this feels like a mystery:
- You’re not broken. Your brain isn’t broken.
- JavaScript’s relationship with
thisis just weird.
Stick with it. Ask questions. Build small things. Watch what happens when you run them. And remember: if this is breaking your brain, you’re probably closer to getting it than you think.