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 personobject.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
thiskeyword is used to make code look cleaner, elegant and easier to reuse.thisis 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
thisand other arguments can be comma separated list. - apply() is used when a function is invoked with its first argument being the value of
thisand other arguments as an array. - bind() creates another function with its first argument being the value of
thisand returns the function without executing it. - Fat arrow functions introduced in ES6 replaced
var self = this;and use lexical scoping forthisbinding.

No comments: