The Magic Of this Keyword

JavaScript borrows this keyword from C++, where it is used to point to an instance of an object from within its own class definition. There is absolutely no confusion about this keyword in C++ because this keyword is never used for any other intent than to point to an instance of an object from its constructor!

Overview

Where It All Begins

function Cat() {
this.name = "felix";
console.log(this); // Cat {name: "felix"}
}
let cat = new Cat(); // Cat {name: "felix"}
class Mouse {
constructor() {
this.name = "mappy";
console.log(this); // Mouse {name: "mappy"}
}
}
let mouse = new Mouse(); // Mouse{name: "mappy"}

The Secondary Purpose Of this Keyword

function abc() {
console.log(this);
}
abc(); // [object Window] -- points to window object
function abc() {
console.log(this);
}
let type = new abc(); // abc{} -- self
typeof type;
function food(kind) {    this.kind = kind;
this.cook = cook; // functions are hoisted, so it's perfectly
// fine to call or assign function names
// before they are defined.
function cook(sec) {
setTimeout(function() {
console.log(this.kind + " cooked for " + sec + " seconds.");
}, sec * 1000);
}
}
let soup = new food("soup"); // <--- this.kind = "soup"soup.cook(2); // undefined cooked for 2 seconds.
function food(kind) {    this.kind = kind;
this.cook = cook; // functions are hoisted, so it's perfectly
// fine to call or assign function names
// before they are defined.
function cook(sec) { // remember, in cook(), this still points to food object
// and not the window object (like in setTimeout)!
// this means we can still capture it here, and pass it
// into setTimeout callback manually, so let's make a
// reference to this and call it that. (or anything you want)
let that = this; // Now inside setTimeout, refer to that.kind not this.kind:
setTimeout(function() {
console.log(that.kind + " cooked for " + sec + " seconds.");
}, sec * 1000);
}
}
let soup = new food("soup");soup.cook(2); // soup cooked for 2 seconds.

You hear a lot about “this binding” — but what in the world is it?

Arrow Functions To The Rescue

function food(kind) {
this.kind = kind;
this.cook = cook;
function cook(sec) {
setTimeout(() => {
console.log(this.kind + " cooked for " + sec + " seconds.");
}, sec * 1000);
}
}
let soup = new food("soup");
soup.cook(2); // soup cooked for 2 seconds.

How to reconcile the two “this” use cases, without losing your mind?

So when does this *not point to [object Window]?

Keep writing code.

Issues. Every webdev has them. Published author of CSS Visual Dictionary https://amzn.to/2JMWQP3 few others…

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store