Welcome to ciysys blog

Avoiding uncertainty with "this" keyword

Published on: 12th July 2017

Updated on: 10th Jan 2022

Overview

Most of the time, we don't know what is the actual this keyword is referring to. Is it a window, jQuery object, or something else. It is difficult to debug and make the code to work.

Solution

One of the easiest solution that I found is to capture the context into self and then all public functions to be declared with the object function. For example, sayHelo() will always referring to the same context as you call the setMyName().

function myClass() {
  var self = this;
  var name;

  self.setMyName = function (s) { name = s; };
  self.getMyName = function() { return name; }; 
  self.sayHelo = function() { return self.getMyName(); };
}

var c = new myClass();
c.setMyName('Mickey');
console.log(c.sayHelo());

The catch of "this" keyword

It does not work in lambda function. For example,

class Customer {
    constructor(n) {
        this.name = n;
    }

    sayHelo() {
        console.log(`helo ${this.name}`);
    }

    sayHeloUsingCallback(cb) {
        cb.apply(this);
    }
}

let o1 = new Customer('Mike');

// output: helo Mike
o1.sayHelo();

// output: helo 3 Mike
// "this keywork runs in the context of "o1".
o1.sayHeloUsingCallback(function() {
    console.log(`helo 3 ${this.name}`);
});

// output: helo 2 undefined
// "this" keyword does not work in lambda function.
o1.sayHeloUsingCallback(() => {
    console.log(`helo 2 ${this.name}`);
});

Another catch is the context could be anything. In the following sample code, it the output is "Mike" instead of "John" because we pass in the o1 context.

let o2 = new Customer('John');

// output:helo Mike
o2.sayHelo.apply(o1);

Conclusion

This is the JavaScript feature which you just need to get used to it.

Jump to #JAVASCRIPT blog

Author

Lau Hon Wan, software developer.