JavaScript the this
Keyword
A summarized note about what I learned on the
this
keyword of JS.
The this
keyword in JavaScript works differently from other programming language. The this
references the object that is currently calling the function. In other words, the object to be bound to this
is determined dynamically (not statically or lexically) depending on how the function is called when the function is called.
Global Context
Global Object means the only top-level object of all objects, which is window
in a browser-side and global
in a server-side (Node.js). Basically, this
is bound to the global object. In the case of global functions, even inner functions and callback functions, this
is bound to the global object, not to the outer function.
var value = 1;
var obj = {
value: 100,
foo: function() {
console.log("foo's this: ", this); // obj
console.log("foo's this.value: ", this.value); // 100
function bar() {
console.log("bar's this: ", this); // window
console.log("bar's this.value: ", this.value); // 1
}
bar();
},
cb: function() {
setTimeout(function() {
console.log("callback's this: ", this); // window
console.log("callback's this.value: ", this.value); // 1
}, 100);
}
};
obj.foo();
obj.cb();
In the strict mode
When we prevent this situation that is this
references the global object when a functions is called. With use strict
, we can make this
points `undefined, rather the global object.
function foo() {
"use strict";
console.log(this === undefined); // true
function bar() {
console.log(this === undefined); // true
}
bar();
}
foo();
Method invocation
When we call an object’s method, this
will mean the object that has the method.
var obj1 = {
name: 'Lee',
sayName: function() {
console.log(this.name);
}
}
var obj2 = {
name: 'Kim'
}
obj2.sayName = obj1.sayName;
obj1.sayName();
obj2.sayName();
However, if we call the method without specifying its object, this
is set to the global object in non-strict mode and undefined
in the strict mode.
// still continued with the above code
var sayName = obj1.sayName;
sayName(); // undefined
To fix this, we can use bind()
, apply()
, call()
to specify an owner of the method, or to clear an object this
has to be bount to.
// still continued with the above code
var sayName2 = obj1.sayName.bind(obj1);
sayName2(); // Lee
Constructor invocation
In JavaScript, if a normal function is called with new
operator, it behaves as a constructor function. JavaScript creates a new object and sets this
to the newly created object. To avoid a confusion, a constructor function is named by capitalizing the first character.
// contructor function
function Person(name) {
this.name = name;
}
var me = new Person('Lee');
console.log(me); // Person {name: "Lee"}
// It does not behave as a contructor function without a 'new' operator
var you = Person('Kim');
console.log(you); // undefined
Arrow Function
In arrow functions, this
is set lexically. In other words, it takes the this
from the outer function of the arrow function, without its own execution context. This is the reason why the arrow functions are useful for callback functions. Moreover, the arrow functions are not recommended to use them as a method of an object, because this
will be lexically scoped.
let getThis = () => this;
console.log(getThis() === window); // true
Sources
Udemy course - JavaScript: The Advanced Concepts Poiemaweb JavaScript Tutorial