As múltiplas personalidades do this em JavaScript

As múltiplas personalidades do this em JavaScript
ricardo.valeriano
ricardo.valeriano

Compartilhe

Se você já escreveu algum código JavaScript, não deve mais achar estranho quando alguém atribui uma função a uma variável. Mas o que exatamente acontece quando você faz isso? Em JavaScript, as funções podem ser passadas como parâmetros para outras funções, retornadas como valor e, como já dito, referenciadas por variáveis. A linguagem trata as funções como cidadãs de primeira classe.

O JavaScript representa funções como objetos. Quando atribuímos uma função a uma variável, estamos criando uma referência para um objeto do tipo function. Podemos ver isso de forma clara utilizando o operador typeof. O exemplo abaixo cria uma função e a atribui a variável chamada apresentar, que recebe como parâmetro um objeto com os atributos nome e email. Vamos invocar a função e a seguir usar o operador typeof para inspecionar o tipo que é referenciado pela variável usada para guardar a função: sourcecode lang="javascript" var apresentar = function(pessoa) { console.log("Eu sou "+ pessoa.nome +" e meu email é: "+ pessoa.email); } apresentar({nome: "Ricardo", email: "[email protected]"}); // Eu sou Ricardo e meu email é: [email protected] typeof(apresentar); // "function" Quando invocamos uma função com o operador (), estamos utilizando uma forma de invocação chamada por alguns de invocação simples. A maneira como uma função é invocada tem efeito direto sobre como a palavra chave this é "atribuída" no corpo da função. Quando seu código JavaScript é executado em um navegador, uma variável global chamada window é criada para representar a própria janela do navegador. E quando a forma simples de invocação é usada, o objeto referenciado por this é equivalente ao window, veja: ```sourcecode lang="javascript" typeof(window); // "object"

Banner promocional da Alura, com um design futurista em tons de azul, apresentando o texto

console.log(window); // DOWWindow

var verificandoWindow = function() { console.log(this); console.log(this === window); } verificandoWindow(); // DOWWindow, true `` Notou que o tipo referenciado porwindowéobject? Podemos criar nossa própria instância deobjectusando a chamada [notação literal](https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Core_Language_Features#Object_literals), que é a que foi usada para criar o parametro passado na invocação da funçãoapresentar` no nosso primeiro exemplo.

A variável window é uma referência para um objeto e podemos adicionar atributos a ele! Quando criamos uma variável fora de uma função (ou seja no escopo- global ), automaticamente um atributo com o mesmo nome da variável é criado em window para referenciar o objeto atribuído a nova variável. Quando tentamos acessar o valor dessas variáveis, estamos, na verdade, recuperando o valor de um atributo de window. Veja o exemplo a seguir: ```sourcecode lang="javascript" var todosPodemMeVer = "porque sou um atributo de window"; console.log(window.todosPodemMeVer); // porque sou um atributo de window

var pessoa = { nome: "Ricardo", email: "[email protected]" } console.log(pessoa.nome); // Ricardo

console.log(window.pessoa === pessoa); // true Toda função tem acesso à palavra chave `this`. Vamos usar isso para obter informações sobre esse objeto. Vamos criar as propriedades _nome_ e _email_ em `window` e alterar a função para buscar os valores usando atributos presentes em `this`, e não mais do objeto recebido como argumento:sourcecode lang="javascript" var nome = "João da Silva"; window.email = "[email protected]"; var apresentar = function() { console.log(this === window); console.log("Eu sou "+ this.nome +" e meu email é "+ this.email); }

apresentar(); // true // Eu sou João da Silva e meu email é [email protected] `` Veja que criamos um atributo novo chamadoemailpara o objeto referenciado porwindow. Um atributo pode referenciar qualquer objeto, inclusive funções. Para ilustrar, vamos criar um novo atributo chamadoquemSouEuempessoa, que é uma referência para a funçãoapresentardo exemplo anterior. Dessa forma, será possível invocar essa função diretamente a partir do objetopessoa`.

 var pessoa = { nome: "Ricardo", email: "[email protected]" } 

Mas a função usa internamente a variável this para fazer seu trabalho, certo? Será que isso vai continuar funcionando? Repare a saída:

 pessoa.quemSouEu = apresentar; pessoa.quemSouEu(); // false // Eu sou Ricardo e meu email é [email protected] apresentar();// Agora novamente invocando a função com o operador () // true // Eu sou João da Silva e meu email é [email protected] 

Uma função referenciada por um atributo de um objeto pode ser invocada como um método daquele objeto, a palavra chave this é atribuída ao objeto onde a função foi invocada. Uma outra forma de executar uma função no contexto de um objeto específico é invocando o método call disponível em todo objeto do tipo function. Esse método possibilita definir o objeto referenciado por this no momento da invocação: sourcecode lang="javascript" apresentar.call(pessoa); // false // Eu sou Ricardo e meu email é [email protected] Mas não pense que acabou! Existem ainda outras formas de invocar funções que interferem em como a palavra this é atribuída. Por exemplo, o operador new pode ser utilizado em associação com o operador () para invocar qualquer função, isso vai fazer com que o this seja atribuído a um novo objeto. O retorno da função também pode ser alterado por essa forma de invocação. Você lerá sobre esses detalhes na segunda parte desse artigo.

Veja outros artigos sobre Front-end