Navigate back to the homepage
📚 Books

The this keyword in Javascript

Mark Pollmann, 
September 5th, 2017 · 2 min read

This post serves as a quick refresher on how the this-keyword works in different contexts in the JavaScript language. It might help someone to not fall for one of the many traps I already fell for.
Note that I will only talk about strict mode here. Sloppy mode has way too many gotchas on its own and is generally discouraged. Going forward, ES6 modules will always be in strict mode, anyway.

this in the global context

Calling this in the global execution context (outside of any function) refers to the global object. In the browser the global object is called window, in Node.js it’s called global. But beware: in node modules the code is wrapped in a wrapper function, so this now points to module.exports.

this in function calls

The this value in a regular function call is undefined (in sloppy mode it referred to the global object):

1"use strict";
2function Foo() {
3 console.log(this);
4}
5Foo(); // undefined

this in constructor calls

Calling a function with new is called a constructor call. A new object will be created and this set as a reference to this instance. This works as expected and is pretty straight-forward:

1function Something(first, second) {
2 console.log(this);
3 this.firstName = first;
4 this.secondName = second;
5}
6const foo = new Something("John", "Doe"); // Something {}
7console.log(foo.firstName); // 'John'

this in method calls

In method calls this refers to its receiver, the object on which the method was invoked on:

1const o = {
2 f: function() {
3 console.log(this);
4 },
5};
6o.f(); // { f: [Function: f] }

Another object could call o.f() and this would still refer to the original o object.

this in call() or apply()

With call and apply you can set the this value for this one time explicitly. They differ only in the way you are able to additionally set arguments: either comma-separated with call or in an array with apply.

1function f(a, b) {
2 console.log(this); // 'new this value'
3 console.log(a); // 'firstArg'
4 console.log(b); // 'secondArg'
5}
6f.call("new this value", "firstArg", "secondArg");
7f.apply("new this value", ["firstArg", "secondArg"]);

If you keep forgetting which one takes an array and which one doesn’t: apply and array both start with a and each has five letters.

this in bind()

ES5 introduced function.prototype.bind(thisArg [, args]). This creates a new function with this permanently bound to the used thisArg (as well as optional, comma-separated, arguments).

1function foo() {
2 console.log(this);
3}
4foo(); // undefined
5const bar = foo.bind("newThis");
6bar(); // 'newThis'

this in arrow functions

Arrow functions don’t bind this (neither arguments, super and new.target):

1function f(a) {
2 const anon = c => {
3 return console.log(arguments);
4 };
5 anon("new arg");
6}
7f("old arg"); // { '0': 'old arg' }

No need for the const self = this hack if used properly.

this in ES6 classes

While I’m not a fan of them, ES6 introduced classes anyway. Under the hood they still work with the JavaScript prototype system and are basically syntactic sugar over it.
this inside a normal class method refers to the instance, in static methods to the class itself.

1class Foo {
2 constructor() {
3 console.log(this);
4 }
5 static bar() {
6 console.log(this);
7 }
8}
9const foo = new Foo(); // instance of Foo
10Foo.bar(); // class Foo

Conclusion

There are lots and lots of edge cases for this that I haven’t talked about here which could fill books. I try to code without this as much as possible and it works out fine (usually).

More articles from Mark Pollmann

Understanding the Kubernetes architecture

How does Kubernetes handle Kubernetes?

January 15th, 2021 · 3 min read

GraphQL - From Beginner To Expert in 2020

GraphQL is growing fast. Created by Facebook in 2012 and released to the public in 2015 it has taken the world by storm. Companies using it…

July 6th, 2020 · 10 min read
© 2017–2021 Mark Pollmann
Link to $https://twitter.com/MarkPollmannLink to $https://github.com/MarkPollmannLink to $https://www.linkedin.com/in/mark-pollmann-961446132/