Métodos de Object em JavaScript e this
Aprenda métodos de object em JavaScript e a palavra-chave this: definição, resolução em tempo de chamada, empréstimo de métodos, encadeamento e arrow functions.
Introdução aos Métodos de Object em JavaScript
Os objects JavaScript são coleções de propriedades, e os métodos de um object são funções armazenadas como propriedades desses objects. Os métodos permitem que um object faça coisas com seus próprios dados, e não apenas os armazene.
Este guia aborda como definir e chamar métodos, como a palavra-chave this conecta um método ao seu object, como ler e modificar o estado do object a partir de seus métodos, e o erro mais comum na linguagem: perder o this em callbacks. Ao final, abordamos a diferença prática entre funções regulares e arrow functions.
Definindo e Chamando Métodos
Um método é apenas uma propriedade cujo valor é uma função. A sintaxe abreviada greet() { ... } é a forma moderna de escrevê-lo; é equivalente a greet: function() { ... }.
greet é um método do object user. Ele usa this.name para acessar a propriedade name do object, demonstrando como os métodos podem operar sobre os dados do próprio object. Você chama um método com a mesma sintaxe de ponto usada para qualquer propriedade, seguida de (): user.greet().
A Palavra-chave this em Métodos
A palavra-chave this refere-se ao object antes do ponto no momento em que o método é chamado. Isso é determinado no momento da chamada, e não quando a função é escrita — é isso que torna o this flexível, mas também propenso a erros.
Exemplo: Usando this em Métodos
No método details, this é usado para referenciar o próprio object person, permitindo o acesso às suas propriedades name e age para produzir uma mensagem personalizada. Como details foi chamado como person.details(), this é person.
Modificando Propriedades de Objects
Os métodos não servem apenas para recuperar valores de propriedades, mas também para atualizá-los.
Exemplo: Atualizando Propriedades
O método promote atualiza a propriedade jobTitle e exibe uma mensagem que reflete a alteração. Isso ilustra como os métodos podem modificar dinamicamente o estado interno de um object.
Usando Métodos para Cálculos
Os métodos também são úteis para realizar cálculos com base nas propriedades do object.
Exemplo: Calculando Valores
O método area calcula a área do retângulo usando as propriedades width e height. Este exemplo mostra como os métodos podem encapsular funcionalidades que operam sobre os dados armazenados num object.
Empréstimo de Métodos
Como o this é resolvido no momento da chamada, a mesma função pode ser executada em diferentes objects. Esta é a base do empréstimo de métodos.
Exemplo: Emprestando um Método
Aqui, o método speak do object dog é atribuído ao object cat. Quando chamado como cat.speak(), this.name refere-se a Whiskers, demonstrando que this depende de como o método é chamado, e não de onde ele foi definido.
Quando não é possível reatribuir o método, mas ainda se deseja emprestá-lo, use call, apply ou bind para definir this explicitamente. Consulte Decorators e encaminhamento, call/apply para um tratamento completo.
introduce.call(alice) executa introduce com this definido como alice, mesmo que introduce seja uma função independente e não uma propriedade de nenhum dos objects.
Encadeamento de Métodos
O encadeamento de métodos permite que vários métodos sejam chamados numa única expressão, fazendo com que cada método retorne this — o próprio object. O object retornado torna-se o alvo da próxima chamada.
Exemplo: Implementando o Encadeamento de Métodos
Cada método em calculator modifica value e retorna o object, permitindo as chamadas encadeadas. Este padrão melhora a legibilidade e é a base de APIs fluentes como jQuery e muitos auxiliares de array.
Funções Tradicionais vs. Arrow Functions
Em JavaScript, o comportamento da palavra-chave this varia significativamente entre funções tradicionais e arrow functions. Compreender essa diferença é o aspecto mais importante para escrever código correto que depende de this.
Sempre tenha cuidado com a perda de contexto de this em callbacks ou ao passar um método como argumento. Nesses casos, this pode não referenciar o object de origem — pode ser undefined (em modo estrito / módulos) ou o object global.
Funções Tradicionais
Numa função tradicional, this é determinado por como a função é chamada. Veja como ele varia:
- Contexto global: Quando uma função é chamada sem nenhum object antes do ponto,
thisé o object global (windowem navegadores,globalno Node) em código não-estrito, eundefinedem modo estrito ou em módulos.
- Métodos de object: Quando uma função é chamada como método de um object,
thisrefere-se a esse object.
- Manipuladores de eventos: Quando uma função tradicional é usada como manipulador de eventos,
thisrefere-se ao elemento que recebeu o evento.
<button id="myButton">Click me</button>
<p id="output">Click the button to see the result.</p>
<script>
document.getElementById("myButton").addEventListener("click", function () {
document.getElementById("output").innerHTML = "This button was clicked: " + this;
});
</script>Arrow Functions
As arrow functions não possuem seu próprio this. Em vez disso, elas capturam o this do escopo léxico ao redor no momento em que são definidas. Isso as torna ideais para callbacks dentro de um método, quando se deseja manter o this do método.
- Contexto consistente em callbacks: Útil quando
thisprecisa permanecer o mesmo dentro de um callback aninhado num método.
Aqui, logActions usa uma arrow function dentro de forEach. A arrow function herda o this de logActions, portanto referencia corretamente userProfile.name. Uma função tradicional passada para forEach receberia seu próprio this (o object global ou undefined), e this.name falharia.
Não use uma arrow function para definir um método de object de nível superior quando você depende de this. Uma arrow function não tem this próprio, portanto herda do escopo ao redor (geralmente o escopo global) em vez do object — this.name seria undefined.
Exemplo Prático
Vamos usar um exemplo realista envolvendo um object que gerencia o perfil online de um usuário, demonstrando os dois tipos de funções lado a lado:
Este exemplo mostra claramente como as arrow functions ajudam a manter o contexto correto (this), especialmente em callbacks aninhados onde o this dinâmico de uma função tradicional falharia silenciosamente.
Perdendo this e Como Corrigir
O bug clássico: você extrai um método para uma variável ou o passa como callback, e this deixa de ser o object.
Quando counter.show é desanexado, chamar show() não tem nenhum object antes do ponto, e this é perdido. bind retorna uma nova função cujo this é fixado permanentemente. A mesma ideia se aplica a setTimeout(obj.method, 1000) (quebrado) versus setTimeout(() => obj.method(), 1000) (funciona). Para um aprofundamento, consulte Vinculação de funções.
Conclusão
Os métodos de object conferem comportamento aos seus dados, e a palavra-chave this é o que conecta um método ao seu object. A regra principal: this é o object antes do ponto no momento da chamada, portanto pode mudar dependendo de como uma função é invocada. Funções regulares recebem um this dinâmico; arrow functions capturam o this lexicalmente, o que é exatamente o que se deseja em callbacks, mas incorreto para métodos de nível superior. Quando this é perdido, recorra a bind, call ou apply.
Para ir além, explore referências e comportamento de cópia de objects, funções construtoras e new, e decorators com call/apply.