
La this
palabra clave sin duda es una de las más utilizadas y, sin embargo, incomprendida en JavaScript. Intentaré cambiar eso hoy.
Volvamos a los buenos tiempos de la vieja escuela, cuando aprendimos sobre los pronombres.
Phelps está nadando rápido porque él quiere ganar la carrera.Note el uso del pronombre "él". No nos dirigimos directamente a Phelps aquí, pero usamos el pronombre él para referirnos a Phelps . De manera similar, JavaScript usa la this
palabra clave como referencia para referirse al objeto en contexto, es decir, el sujeto .
Ejemplo:

var car= {make: "Lamborghini",model: "Huracán",fullName: function () {console.log(this.make+" " +this.model);console.log(car.make+ " " +car.model);}}car.fullName();
En el código anterior, tenemos un objeto car
que tiene las propiedades make
, model
y fullName
. El valor de fullName
es una función que imprime el nombre completo del automóvil utilizando 2 sintaxis diferentes.
- El uso de
this
= & gt; this.make+” “ +this.mod
elthe t
his se refiere al objeto en contexto cuyois c
arso this.ma
ke es efectivoly car.m
ake y asíis this.mo
del. - Usando la notación de puntos, podemos acceder a las propiedades de los objetos,
car.make
&car.model
.
this
¡Lo es!
Ahora que hemos entendido qué es this
y su uso más básico, hagamos algunas reglas generales para que siempre podamos recordar.
La this
palabra clave JS se refiere al objeto al que pertenece.
var car={make:'....'func:()=>{console.log(this.make)}}
El this
del fragmento anterior pertenece al objeto car.
Toma diferentes valores dependiendo del uso
- Dentro de un método.
- Dentro de una función.
- Solo.
- En un evento.
call()
yapply().
Dentro de un método
Cuando this
se usa dentro de un método, se refiere al objeto propietario.
Las funciones definidas dentro de un objeto se denominan métodos. Tomemos de nuevo nuestro ejemplo del coche.
var car= {make: "Lamborghini",model: "Huracán",fullName: function () {console.log(this.make+" " +this.model);console.log(car.make+ " " +car.model);}}car.fullName();
fullName()
aquí hay un método. El this
interior al que pertenece este método car
.
Dentro de una función
this
dentro de una función es un poco complicado. Lo primero que hay que entender es que, como todos los objetos tienen propiedades, las funciones también tienen propiedades. Siempre que se ejecuta esa función, obtiene la this
propiedad, que es una variable con el valor del objeto que la invoca.
Si la función no es invocada por un objeto, entonces el this
interior de la función pertenece al objeto global, que se llama ventana. En este caso, se referirá a los valores definidos en el ámbito global. Veamos un ejemplo para una mejor comprensión:
var make= "Mclaren";var model= "720s"function fullName(){ console.log(this.make+ " " + this.model);}
var car = { make:"Lamborghini", model:"Huracán", fullName:function () { console.log (this.make + " " + this.model); }} car.fullName(); // Lmborghini Huracán window.fullName(); // Mclaren 720S fullName(); // Mclaren 720S

Aquí make, model
y fullName
se definen globalmente, mientras que el car
objeto también tiene una implementación de fullName
. Cuando lo invoca el car
objeto, esto se refiere a las propiedades definidas dentro del objeto. Por otro lado, las otras dos funciones son las mismas y devuelven las propiedades definidas globalmente.
Solo
Cuando se usa solo, no dentro de ninguna función u objeto, se this
refiere al objeto global.

El this
que aquí se refiere a la propiedad de nombres global.
En un evento
Events can be of any type, but for the sake of simplicity and clarity, let’s take a click event.

Whenever a button is clicked and an event is raised, it can call another function to do a certain task based on the click. If this
is used inside that function, it will refer to the element which raised the event. In the DOM, all the elements are stored as objects. That is why when an event is raised it refers to that element, because that webpage element is actually an object inside the DOM.
Example:
Remove Me!
call(), apply() & bind()
- bind: allows us to set the
this
value on methods. - call & apply: allow us to borrow functions and set the
this
value on function invocation.
Call, Bind and Apply are in themselves a topic of another post. They are very important, and explaining them here is not possible as we should know all about this
to know the usage of these functions.
The trickiest part
If understood well, this
make our work easier in a way. But there are some cases where it is misunderstood.
Example 1.

var car = {make:"Lamborghini",model:"Huracán",name:null,fullName:function () {this.name=this.make + " " + this.model;console.log (this.name);}}
var anotherCar={make:"Ferrari",model:"Italia",name:null}
anotherCar.name= car.fullName();
We get an unexpected result here. We borrowed a method that uses this
from another object, but the problem here is that the method is only assigned to anotherCar
function but is actually invoked on car
object. That’s why we get the result as Lamborghini and not Ferrari.
To resolve this, we use the call()
method.

Here the call()
method calls fullName()
on anotherCar
object which originally does not have the fullName()
function.
We can also see that, when we log the car.name
and anotherCar.name
we get the result for the latter not on former, which means that the function was indeed invoked on anotherCar
and not on car
.
Example 2.

var cars=[{ make: "Mclaren", model: "720s"},{make: "Ferrari",model: "Italia"}]
var car = {cars:[{make:"Lamborghini", model:"Huracán"}],fullName:function () {console.log(this.cars[0].make + " " + this.cars[0].model);}}var vehicle=car.fullName;vehicle()
In the above snippet we have a global object called cars and we have the same name object inside the car object. The fullName()
method is then assigned to the vehicle variable which is then called. The variable belongs to the global object so this
calls the global cars
object instead of the cars
object because of the context.
To resolve that we use .bind()
function to solve the issue.

Binding helps us with specifically setting the this
value and hence the vehicle variable explicitly points to the car object and not the global object, so this lies in the context of the car
object.
Example 3.

var car = {cars:[{make:"Lamborghini",model:"Huracán"},{ make: "Mclaren", model: "720s"},{make: "Ferrari",model: "Italia"}],fullName:function(){this.cars.forEach(()=>{console.log (this.make + " " + this.model);})}}car.fullName();
In the above snippet, the fullName()
calls upon a function which iterated through the cars array using forEach
. Inside the forEach
there is an anonymous function where this loses context. A function inside a function in JavaScript is called a closure
. Closures
are very important and widely used in JavaScript.
Another important concept playing a role here is scope
. A variable inside a function cannot access variables and properties outside its scope
. this
inside the anon function cannot access this
outside it. So this
has nowhere to go but to point to global object. But there, no property is defined for this
to access so undefined
is printed.
A workaround for the above is that we can assign a variable the value of this
, outside the anonymous function and then use it inside it.

Here, the self variable contains the value of this
which is used with the inner function thus giving us the output.
Example 4.

var car= {make: "Lamborghini",model: "Huracán",fullName: function (cars) {cars.forEach(function(vehicle){console.log(vehicle +" "+ this.model);})}}car.fullName(['lambo','ferrari','porsche']);
This is a revisited example, in which this
wasn't accessible so we preserved it's value by using a variable called self. Let's use arrow function to solve the same:

As you can see, using an arrow function in forEach()
automatically solves the problem and we don’t have to do bind, or give the this
value to some other variable. This is because arrow functions bind their context so this
actually refers to the originating context, or the originating object.
Example 5.

var car= {make: "Lamborghini",model: "Huracán",fullName: function () {console.log(this.make +" "+ this.model);}}var truck= {make: "Tesla",model: "Truck",fullName: function (callback) {console.log(this.make +" "+ this.model);callback();}}truck.fullName(car.fullName);
The above code consists of two identical objects, with one containing a callback function. A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine.
Here, the truck object’s fullName
method consists of a callback which is also invoked inside it. Our car object is as before. When we invoke the truck’s fullName
method with the callback(argument) as the fullName
method of the car object, we get output as Tesla Truck
and undefined undefined.
After reading about this
some of you might have gotten a hunch that car.fullName
would print the model and make of the truck object, but to your disappointment, this
again played a trick on us. Here the car.fullName
is passed as an argument and is not actually invoked by the truck object. The callback invokes the car object method, but note that the actual call site for the function is the callback which binds this to the global object. It's a bit confusing, so read it again!

Here to get clarity, we print this
itself. We can see that the this
of callback is given a global scope. So to get a result we create global make
and model
properties.

Again, running the same code with global make
and model
properties we finally get the answer to the global this
. This proves that this
references the global object.
To get the results which we desire, the car.fullName
result we will again use bind()
to hard-bind the car object to the callback, which will make everything right again.

Solved!
No doubt that this
is very useful, but has it's own pitfalls too. Hope I made it quite easy for you to understand. If you want more content simplified like this, follow me on Medium. Please leave your responses and share this if you liked it.
