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 this is 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.