What's this in JS?
If you work in JavaScript or any other programming language, you may have used
this
. However, this
in JavaScript works differently than in other languages. There have been so many misconceptions about the use of this
leading to its improper use and thus, causing errors. In this post, we'll try to understand the better use of this
.Jim likes coffee. Jim likes tea as well. // Without the use of "Pronoun"
Jim likes coffee. He likes tea as well. // With the use of "Pronoun"
As in the second sentence, the introduction of "He" as a pronoun makes the sentence look better than the first one,
this
keyword is also used in writing neat and elegant code.Consider the following code:
function username(person) {
return person.name.toUpperCase();
}
function greeting(person) {
var salutation = "Hello" + " " + username(person);
console.log(salutation);
}
var jack = {
name : "Jack"
}
var jill = {
name : "Jill"
}
greeting(jack); //Hello JACK
greeting(jill); //Hello JILL
and now the following code using
this
keyword instead of passing person
object to both username
and greeting
functions.
function username() {
return this.name.toUpperCase();
}
function greeting() {
var salutation = "Hello" + " " + username.call(this);
console.log(salutation);
}
var jack = {
name : "Jack"
}
var jill = {
name : "Jill"
}
greeting.call(jack); //Hello JACK
greeting.call(jill); //Hello JILL
The difference between the above two code snippets is that this
has allowed both username
and greeting
functions to reuse the person object without creating a separate function for each object. We didn't define person
object separately for username
and greeting
functions. Thus, this
keyword has made our code cleaner and easier to re-use by indirectly passing along object reference.
What matters for this
?
The only thing matters for this
binding is where the function is invoked instead of where and how it is declared. The appropriate use of this
can be determined by nature of invoking a function while it is being executed.this
does not refer to the function itself.This is the most common misconception about
this
in JavaScript. We'll look into some scenarios where the value of this
is determined by how the function is called.Global Context
function username() {
console.log(this.name);
}
var name = "Jill";
username(); //Jill
In the above snippet of code, function
username
is invoked in an ordinary manner which is a standalone function invocation. By default, this
binding will point to the global object which in this case is globally defined name
. Hence, this
is bound to name
.Object method
function username() {
console.log(this.name);
}
var person = {
name : "Jill",
username : username
}
person.username(); //Jill
Again, it is all about how the function is invoked. This time, it is invoked using Object reference.
username
is defined twice but it is not relevant when choosing how to bind this
. ( : It's not about how the function is declared, it is about how it is called).However,
person
object "owns" the username
function reference at the time the function is called. In this scenario, object should be used for the function call's this
binding. Hence, this.name
is bound to person.name
Without reference in an object
In the above example, we saw that function was declared inside an object as well. Hence, the function reference was called using object. What if in a typical scenario, we don't have a function reference on an object but we still want to force a function call using that object forthis
binding?Here come to play
call
, apply
and bind
call
function username() {
console.log(this.name);
}
var person = {
name : "Jill",
}
username.call(person); //Jill
username.call()
forces this
to be person
explicitly without having username
function reference on person
object.apply
function person(name, age) {
console.log("Our first User is " + name + ", a " + this.gender + " of " + age + " years old");
}
var firstUser = {
gender : "female",
}
person.apply(firstUser, ["Jill", 25]); //Our first User is Jill, a female of 25 years old
person.apply
works the same way as person.call
does. Both differ in number of arguments each can supply.The main difference is that apply
lets you invoke the function with arguments as an array; call
requires the parameters be listed explicitly using commas.Their syntaxes differ as in :
function.apply(valueOfThis, arrayOfArgs);
person.apply(firstUser, [Jill, 25]);
function.call(valueOfThis, arg1, arg2, ...);
username.call(person);
Tip: a for arrays in apply and c for commas (separated list) in call.
bind
bind() creates a new function and in the new functionthis
is permanently bound to the first argument of the bind
function. Unlike call()
and apply()
, bind()
is not invoked immediately and rather creates a new function with a given this
value and returns that function without executing it.
function add(a) {
console.log(this.b, a);
return this.b + a;
}
var myNumber = {
b : 4
}
var something = add.bind(myNumber);
var myValue = something(3); //4 3
console.log(myValue); // 7
this
lexically
In ES6, the fat arrow functions (using fat arrow operator =>) use lexical scoping for binding this
to the enclosing function.In global code, it will be set to the global context.
function name(){
return (firstName) => {
console.log(this.firstName);
};
}
var person1 = {
firstName : "Jill"
}
var person2 = {
firstName : "Jack"
}
var personName = name.call(person1);
personName.call(person2); //Jill
In the above code snippet, the fat arrow operator in the function
name
captures this
at the time function is invoked. Since name
has this
bound to person1
, so personName
will also be bound to person1
. It is important to remember that lexical binding of fat arrow function cannot be overridden. It is a replacement of var self = this;
from ES versions existings before ES6.TL;DR
this
keyword is used to make code look cleaner, elegant and easier to reuse.this
is a binding whose reference depends entirely on where the function is invoked rather than where it is declared.- call() is used when a function is invoked with its first argument being the value of
this
and other arguments can be comma separated list. - apply() is used when a function is invoked with its first argument being the value of
this
and other arguments as an array. - bind() creates another function with its first argument being the value of
this
and returns the function without executing it. - Fat arrow functions introduced in ES6 replaced
var self = this;
and use lexical scoping forthis
binding.
No comments: