entendo a palavra-chave this em javascript
Introdução
No JavaScript a palavra-chave this
se refere a um objeto, agora o objeto em que ele faz referência depende de como this
está sendo usado ou chamado, o this
se comporta um pouco diferente se comparado com outras linguagens, sem falar ele também possui algumas diferenças quando está no modo estrito e o modo não estrito.
Como o this é definido?
this
aponta para quem fez a chamada da função, mais não a função em si, a função pode ter diferentes valores de this
dependendo do cenário como por exemplo: se uma função for chamada como um método de um objeto, o valor de this
será o objeto, mais se a função for chamada sem nenhum objeto como contexto, o valor de this
será o objeto global, veja logo em baixo alguns exemplos de como o valor de this
é diferente dependendo do cenário:
1. No contexto global
Quando uma função é chamada diretamente sem nenhum objeto como contexto, o this
é definido como o objeto global.
function cumprimentar() {
console.log(`Olá, meu nome é ${this.nome}.`);
}
cumprimentar(); // "Olá, meu nome é undefined."
2. Em um método de objeto
Quando uma função é chamada como um método de um objeto, o this
é definido como o próprio objeto. Por exemplo:
const pessoa = {
nome: "João",
cumprimentar() {
console.log(`Olá, meu nome é ${this.nome}.`);
}
};
pessoa.cumprimentar(); // "Olá, meu nome é João."
3. Em funções "call", "apply" e "bind"
Você também pode chamar uma função diretamente e definir o valor de this
usando o métodos call
, apply
ou bind
O método call
aceita uma lista de argumentos separados por vírgulas, enquanto o método apply
aceita um array de argumentos. Por exemplo:
const pessoa1 = {
nome: "João"
};
const pessoa2 = {
nome: "Maria"
};
const pessoa3 = {
nome: "Albert"
}
function cumprimentar() {
console.log(`Olá, meu nome é ${this.nome}.`);
}
cumprimentar.call(pessoa1); // "Olá, meu nome é João."
cumprimentar.apply(pessoa2); // "Olá, meu nome é Maria."
cumprimentar.bind(pessoa3)(); // "Olá, meu nome é Albert."
Lembrando que a função
bind
cria uma nova função que, quando chamada, tem sua palavra-chavethis
definida com o valor fornecido, com uma sequência determinada de argumentos precedendo quaisquer outros que sejam fornecidos quando a nova função é chamada, muito usada em handle de eventos de bots discord.
4. Em Construtor
Em uma função construtora o this
é definido como um novo objeto vazio que é criado a partir do protótipo da função.
function Pessoa(nome) {
this.nome = nome;
this.cumprimentar = function() {
console.log(`Olá, meu nome é ${this.nome}.`);
};
}
const pessoa1 = new Pessoa("João");
const pessoa2 = new Pessoa("Maria");
pessoa1.cumprimentar(); // "Olá, meu nome é João."
pessoa2.cumprimentar(); // "Olá, meu nome é Maria."
5. Em Arrow functions
Nas arrow functions , o this
é definido lexicalmente, isto é, seu valor é definido pelo contexto de execução onde está inserido. Em um código global, this
assume o objeto global:
const globalObject = this;
let foo = (() => this);
console.log(foo() === globalObject); // true
Não importa como foo
é chamado, o this
continuará como o objeto global, isto continua verdadeiro mesmo se chamá-lo como método de um determinado objeto, com call
ou apply
ou bind
é usado:
// Chama como um método de um objeto
const obj = { foo: foo };
console.log(obj.foo() === globalObject); // true
// Tentativa de definir this usando call
console.log(foo.call(obj) === globalObject); // true
// Tentantiva de definir this usando bind
foo = foo.bind(obj);
console.log(foo() === globalObject); // true
6. No Modo estrito
Como o código a seguir não está no modo estrito, o valor de this
não é definido pela chamada. Por padrão, this
será o objeto global que no navegador é o window.
function f1() {
return this;
}
// No navegador
f1() === window; // true
Em modo estrito, o valor de this
permanece seja qual for o definido ao entrar no contexto de execução, assim, no caso a seguir, this
por padrão será undefined
function f2 (){
"use strict"; // assume modo estrito
return this;
}
f2() === undefined; // true
Portanto, em modo estrito, se this
não for definido durante o contexto da execução, ele permanecerá como undefined
.
No segundo exemplo,
this
deveria serundefined
, porque f2 foi chamada diretamente e não como um método ou popriedade de um objeto, esta característica não foi implementada em alguns navegadores quando começaram a dar suporte ao strict mode. Como resultado, eles incorretamente retornavam o objeto window.
7. Em funções aninhadas
Em funções aninhadas, o valor de this
pode ser bem confuso, pois uma função pode ter um valor de this
que pode não ser o mesmo da função pai, isso pode ser resolvido usando a função bind()
para vincular o valor de this
a função aninhada:
const pessoa = {
nome: "João",
amigos: ["Maria", "Pedro", "Paula"],
listarAmigos() {
this.amigos.forEach(function(amigo) {
console.log(`${amigo} é amigo de ${this.nome}.`);
}.bind(this));
}
};
pessoa.listarAmigos();
// "Maria é amigo de João."
// "Pedro é amigo de João."
// "Paula é amigo de João."
Conclusão
A palavra-chave this
é muito útil para poder referenciar o objeto atual, muito utilizada em funções construtoras e classes principalmente, porem muita das vezes ela pode parecer muio confusa em diversas situações, então tem que ficar atento aos detalhes.
Agradecimentos
Obrigado por ler até aqui ❤️, acredito que apenas isso já é o suficiente, caso tenha algo a mais, me diga nos comentários para eu adicionar.