This
O this certamente é uma das coisas em JavaScript que é complicado para quem nunca teve contato com uma linguagem de programação orientada a objeto entender. Vamos fazer uma forcinha para entender nesse módulo, ok?
O this é uma palavra chave que pode se referenciar à diversas coisas, baseando-se em onde ele é usado.
Então, vamos tentar explicar o this em lugares diferentes.
Para todos os efeitos, iremos considerar a execução dos comandos apenas fora do modo estrito. Caso você não saiba o que é o modo estrito do JavaScript e tenha interesse em saber, vale a pena a leitura do link abaixo:
O modo estrito do JavaScript - MDN
Tempo médio de leitura: 25 minutos
“Solto” no código ( No navegador )
Quando usamos a palavra chave this solto no código, ou seja, no nosso contexto global (sem estar dentro de uma função, objeto, método, etc), dentro de um navegador, estamos nos referindo ao nosso objeto window.
Você irá ver mais em detalhes o objeto window em outro módulo, então não vamos nos ater muito aqui.
console.log(this === window);
// true
console.log(window.document == this.window.document);
// true
“Solto” no código ( No Node )
Quando usamos a palavra chave this solto no código, ou seja, no nosso contexto global (sem estar dentro de uma função, objeto, método, etc), this se refere ao objeto global.
Podemos ver o objeto global simplesmente com a linha de código abaixo escrita dentro do terminal do node:
this
Isso vai nos dar um objeto enorme, que é o nosso objeto global. Vale lembrar que para isso funcionar, não podemos executar esse código em um arquivo JavaScript, precisará ser direto no terminal do Node.
Para isso, basta instalar o Node e digitar node no terminal.
Podemos até brincar um pouco com isso:
this
//Mostra o objeto global
let a = this
a
//Mostra o objeto global
a == this
// true
this.propCustomizada = 12
this.propCustomizada
// 12
a.propCustomizada
// 12
this.propCustomizada === a.propCustomizada
// true
Dentro de uma função:
Dentro de uma função simples, se referenciar ao this tem o mesmo efeito de se referenciar no contexto global, ou seja, vai se referenciar ao objeto window nos navegadores e ao objeto global no Node.
No navegador:
function testeThis(){
return this
}
testeThis();
// window
console.log(testeThis() == this);
// true
No Node (terminal):
function teste(){return this}
teste()
// Mostra o objeto global
this === teste()
// true
Existe um outro tipo de função com um outro tipo de this, elas são as Arrow Functions, mas não se preocupe, elas são tão importantes que existe um tópico só para elas depois deste, então se segurem um pouco aqueles que estavam ansiosos pela explicação das Arrow Functions.
Dentro de um método
Agora as coisas estão ficando interessantes! Quando usamos a palavra reservada this dentro de um método de um objeto, o this se refere ao objeto que possui esse método.
Isso podemos ver em um arquivo JavaScript e é igual para o Node e para os Navegadores:
let a = {
propriedade: "123",
metodo: function(){
return this.propriedade;
}
}
this.propriedade = "789";
console.log(this.propriedade === a.metodo());
// false
console.log(a.propriedade === a.metodo());
// true
console.log(a.metodo());
// "123"
a.outroMetodo = function(param){
this.propriedade = param;
}
a.outroMetodo("456");
console.log(a.metodo());
// "456"
console.log(a.propriedade === a.metodo());
// true
Call e Apply
Call e Apply são métodos nativos de toda função JavaScript (todas as funções possuem), que possuem uma tarefa em geral: Executar a função com um this personalizado.
A unica diferença é no modo que você chama essas funções:
- Call: Recebe vários parâmetros, o primeiro deles sendo o objeto que será tratado como this e o restante serão os parâmetros que a função a ser executada recebe.
- Apply: Recebe dois parâmetros, o primeiro sendo o objeto que será tratado como this e o segundo sendo um array contendo os parâmetro que a função a ser executada recebe.
Podemos ver como essas funções funcionam abaixo, sempre que chamamos uma função com call, mostramos como podemos chamá-la com apply:
function somaAB(multA, multB){
return this.a*multA + this.b*multB
}
let obj1 = {
a: 10,
b: 5
}
let obj2 = {
a: 7,
b: 2
}
somaAB.call(obj1, 1, 1);
somaAB.apply(obj1, [1,1]);
// 15 ( 10*1 + 5*1 )
somaAB.call(obj1, 2, 3);
somaAB.apply(obj1, [2,3]);
// 35 ( 10*2 + 5*3 )
somaAB.call(obj2, 1, 1);
somaAB.apply(obj2, [1,1]);
// 9 ( 7*1 + 2*1 )
somaAB.call(obj2, 2, 3);
somaAB.apply(obj2, [2,3]);
// 20 ( 7*2 + 2*3 )
O this pode dar medo e parecer complexo demais, porém, seu entendimento é de vital importância para ser um bom desenvolvedor JavaScript, e essencial para ser um desenvolvedor React, então, recomenda-se que se brinque com o this, principalmente com call e apply para entender como ele funciona.
No próximo módulo, iremos explorar como o this muda drasticamente no contexto das queridas Arrow Functions, então, tente entender bem esse módulo antes de avançar.