Working with JavaScript this
keyword can be tricky. Coming from a background of using Ruby, my first assumption was that it was similar to the ‘self’ keyword in Ruby but JavaScript’s this
is much more powerful. this
refers to the current object (the calling object) but in JavaScript, you can assign it a different context.
As with most things in coding, it is good to know the theory properly so you can jump in and make the most of the methods, so you don’t end up with code that you don’t understand. In order to explain the this
keyword, I am going to use call()
, apply()
and bind()
to demonstrate how you can set the ‘this’ value.
The this
keyword, allows you to reuse functions with different contexts which means you get to decide which object should be focal when invoking a function. In order to figure out what this
is referring to, first, look for where the function is invoked and look to the left of the dot. call()
, apply()
and bind()
are explicit methods of setting the execution context.
In the following example, student
is to “the left of the dot” which means the this
keyword is referencing the student
object. So, it’s as if, inside the greet
method, the JavaScript interpreter changes this
to student
. Similarly, for the second example call, mother is to the left of greet, so this
will be interpreted as student.mother.
The following should give you a basic idea of what this can do.
const student = {
name: ‘John’,
age: 25,
greet() {console.log(`Hello, my name is ${this.name}`)}
mother: {
name: ‘Mary’,
greet() {console.log(`Hello, my name is ${this.name}`)}
}
}student.greet() //=> Hello my name is John
student.mother.greet() //=> Hello my name is Mary
call()
call()
is a property that can be used on every function that allows you to invoke the function specifying in what context the function is being invoked. It allows you to override the execution context and set it to the first argument which is then accessed via ‘this; in the function. Additional parameters to the function may be listed after. In the example below, the first argument is student so this will be the focal object and what this’
is referring to.
function greet (l1, l2) {
console.log(`Hello, my name is ${this.name} and I know ${l1} and ${l2}`)
}const student = {
name: ‘John’,
age: 25
}const languages = [‘Ruby’, ‘JavaScript’]greet.call(student, languages[0], languages[1])//=> Hello my name is John and I know Ruby and JavaScript
apply()
In the example above, can you think of a way to JavaScript could make things easier? It would be useful if you could just pass in the languages array…and you can! apply()
allows us to change our code to the following. Note that in the case of apply
, the contents in the Array
get destructured and passed to the function like arguments inside of a ()
. Just like with call()
the first argument is what this will refer to but any additional parameters to the function will be stores in the second argument which is usually an array.
greet.apply(student, languages)//=> Hello my name is John and I know Ruby and JavaScript
To be clear, the is the fundamental difference between apply()
and call()
is that call()
accepts an argument list while apply()
accepts a single array of arguments as the second parameter.
bind()
bind() is very similar to call()
except it returns a new bound function which you can invoke at a later time. In the case of bind, execution context is locked in the function.
const greetFn = greet.bind(student, languages[0], languages[1])
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/call
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/apply
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind