Avoiding uncertainty with "this" keyword
Published on: 12th July 2017
Updated on: 5th Jan 2025
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 confusing in a function and function chaining but it is easier and intuitive within class
. You just need to get used to it. Good luck.
Jump to #JAVASCRIPT blog
Author
Lau Hon Wan, software developer.