O operador this é um dos maiores responsáveis por erros e pegadinhas em um código JavaScript. Entender o seu mecanismo de funcionamento e criação é um grande passo para tirar maior proveito da linguagem.
Contexto de execução
Toda função JavaScript, ao ser executada, gera uma associação do objeto criado pelo interpretador através da palavra reservada this. A especificação da ECMAScript chama isso de ThisBinding, um evento que acontece toda vez que um código JavaScript é executado e um novo contexto de execução é estabelecido. O valor do this é constante e ele existe enquanto este contexto de execução existir.
No browser, o this “padrão” referencia o objeto global window. Toda função declarada no escopo global também vai possuir o objeto window como valor do this (no strict mode vai ser undefined).
Objetos
Quando uma função representa um método de um objeto, o valor do this passa a ser o objeto referenciado. Por exemplo:
O mesmo acontece quando um objeto é criado utilizando uma função construtora, só que nesse caso o this representa o objeto instanciado.
Callbacks & Eventos
Um dos erros mais comuns acontece quando utilizamos a palavra reservada this dentro de um callback e confundimos seu valor. O this dentro do callback vai guardar o valor do objeto pai da função callback e não da função que recebe o callback.
Para esses casos especiais, podemos definir o valor do this utilizando os métodos call e apply (falo mais sobre eles logo, logo).
Outro ponto que merece atenção é o uso do this na hora de anexar eventos a um elemento. Nesse caso, o valor da palavra reservada representa o elemento e não a função.
Aqui a solução é armazenar o estado do objeto em uma variável, normalmente chamada de that ou self e utilizá-la na função do evento.
call & apply
Os métodos call e apply permitem que seja definido um valor para o this de uma função. Vejamos o nosso exemplo de callback, agora utilizando uma chamada com o método call:
Notem que o valor retornado pelo log do console agora foi o próprio objeto ao invés do objeto global window. Isto porque executamos o callback através do método call, definindo o valor do this no contexto de execução como sendo o this do objeto.
Sobre os métodos call e apply, a principal diferença entre eles é que um permite a passagem de argumentos utilizando um array enquanto o outro aceita os argumentos como strings:
Referências
- MDN – this
- MDN – apply
- MDN – call
- Scope in JavaScript