This keyword is a concept that is not too difficult in JavaScript if we grasp the concept of this keyword. This is a series of articles about this keyword to help people master the concept of this keyword.
The goal of
the article will help you better understand this keyword. Will help you shorten
your code. Also being able to understand how this works makes debugging or fix
bug easier.
This keyword
in JavaScript is different from the concepts of this in another languages. We
cover the basic concepts in this article.
To
understand this keyword well. You should have a good understanding of the
concept of functions in JavaScript. This is an article about types of function. Types of function
Table of
content
· What is this keyword?
· This keyword in every context
· Method vs function
· Function declaration vs Function expression vs Arrow function vs Function contructor
What is
this keyword?
When
describing a real-life object. We usually refer to the properties of that
object, the actions of that object. To distinguish and identify that object.
In
JavaScript, objects will be described through properties, methods (the next
section will distinguish methods and functions).
To
understand simply, the object that calls this keyword, this keyword will refer
to that object.
This
keyword in every context
Let's look
at the example below to see how this is defined in each context.
In Object
context:
const globalObject = {
name: 'Global object',
article: 'This keyword',
funcTest: function () {
return this
}
}
console.log(globalObject.funcTest())
// => Object { name: "Global object", article: "This keyword", funcTest: funcTest() }
As you can
see, globalObject called (dot) the funcTest() method, this points to the
globalObject object itself. Applying the knowledge about the types of
functions, we see that the function funcTest() is a function expession. And
when the function expression is inside an object it will be called a method.
In global
context, what object will this refer to?
console.log(this)
// => Window object
In addition
to global (Window) in JavaScript, there is always an object called Window. When
this is called outside of this environment, it is calling the Window object
itself.
Let's look
at an example of a function declaration:
function useThis() {
return this
}
console.log(useThis()) // => Window object
The function
declaration always has its own context and its own this keyword each time it is
called. This keyword in function declaration will always refer to the Window
object no matter how many layers the function has nested. Let's see the proof
below:
function useThis() {
console.log(this) // => Window object
function useThisx2() {
console.log(this) // => Window object
function useThisx3() {
console.log(this) // => Window object
}
useThisx3()
}
useThisx2()
}
useThis()
Method vs
Function
A function
expression that is contained directly by an object is called a method. Now the
function expression (method) will have the context which is the object object
containing it.
Let's see an
example of a function inside a method, which object this keyword will point to?
const globalObject = {
article: 'Learn about this keyword',
logArticleName: function () {
console.log(this)
//=>
Object { article: "Learn about this keyword", logArticleName:
logArticleName() }
function logThisKeyword() {
console.log(this) // => Window object
}
logThisKeyword()
}
}
globalObject.logArticleName()
The example
is still true to the theory. That is, which method is called from an object
(here is method logArticleName()) then this keyword will point to the object
itself. The function (here, logThisKeyword()) has its own context and this
keyword and always points outside the Window object.
Function
declaration vs Function expression vs Arrow function vs Function contructor
Let's look at the example below and go into the analysis of this keyword in every function.
function User(firstName, lastName) {
this.firstName = firstName
this.lastName = lastName
console.log(this)
// =>
Object { firstName: "aka", lastName: "tak" }
}
User.prototype.expressionFunction = function () {
console.log(this)
// =>
Object { firstName: "aka", lastName: "tak" }
function declarFunction() {
console.log(this)
//
=> Window object
}
const arrowFunction = () => {
console.log(this)
//
=> Object { firstName: "aka", lastName: "tak" }
}
declarFunction()
arrowFunction()
}
const aka = new User('aka', 'tak')
aka.expressionFunction ()
First, we
have this keyword in function constructor. This keyword is not initially
assigned to any object. And when called by const aka, this keyword is
referenced to the object calling the method expressionFunction().
Coming to
expressionFunction() as described above, the expression function when
prototyped for an object or inside an object is called a method. And of course,
will point to the object calling it.
Function
declaration has its own context and in any case this keyword in function
declaration always points to Window object.
Finally, the
arrow function. An arrow function has no context of its own, and this keyword
inside an arrow function will always point to the nearest object that contains
it. In this case object aka.
To
summarize, we can see that the function declaration function has its own context,
and this keyword always points to the Window object. Arrow function does not
have its own context and this keyword will point to the object calling it
similarly for function constructor and function expression.
This
keyword in strict mode
Let's go
through another example. We put the function in strict mode. If you don't know
about strict mode, I have an article about strict mode.
function logThis() {
return this
}
const anotherLogThis = () => {
return this
}
console.log(logThis()) // => undefined
console.log(anotherLogThis()) // => Window object
Let's see
the above example in strict mode, the default function cannot point to a Window
object and is assigned the value undefined. The arrow function does not have
its own context, so this will always refer to the nearest object containing it.
In this case the Window object.
Event
Handlers context
<button onclick="console.log(this)">Click me!</button>
We have a
button and an event is click. When clicked, this keyword will be printed. Let's
see which object this keyword here will point to?
<button onclick="console.log(this)">Click me!</button>
<!--
<button onclick="console.log(this)"></button> -->
It returns
the object calling it. In this case the button object whose event is
onclick="console.log(this)".
const button = document.querySelector('button')
button.onclick = function showThisKeyWord() {
console.log(this)
// =>
<button>
}
This is the
same thing that the JavaScript engine does. The button object calls the click
event, and this keyword points to the button object itself. Still true to the
original theory. Any object that calls this, this will point to the object
itself.
Call(),
apply() function
Let's go
through the two methods call() and apply(). These two methods are predefined.
The purpose is call a method of an object, substituting another object for the
current object.
const person = {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
const person1 = {
firstName: 'aka',
lastName: 'tak'
}
console.log(person.fullName.call(person1))
// => aka tak
With our theory, if you call the method person.fullName(), it will definitely output undefined. When we use the .call() method, we assign this keyword to person1. We have both met the requirements of this keyword, and assigned this keyword to the object we want.
In part 2 we will apply the features of the .call() method to other methods to accomplish more purposes.
Conclusion
We just went
through part 1 about this keyword. We've agreed on which object the call to
this keyword will point to the object itself. A function inside an object is
called a method. And a function that is separate or inside a method is still considered
a function. The difference between the types of function is that the declaration
function has its own context and this keyword and always refers to the Window
object. The arrow function has no context and this keyword. So, this keyword
will be pointed to the object that has the closest context containing it.
There are
cases where our theory is wrong. We will discuss these issues together in
continous articles.
Thank you
for joining with me! If you have any ideas, feel free to comment below. Have a
good day!
0 Nhận xét