Remover a palavra-chave “this” do JavaScript torna-a uma linguagem melhor. Aqui está o porquê.

Cristi Salcescu Blocked Unblock Seguir Seguindo 8 de janeiro Foto de Kevin Ku no Unsplash

this é obviamente a fonte de muita confusão no JavaScript. A razão é que this depende de como a função foi invocada, não onde a função foi definida.

JavaScript sem this parece uma linguagem de programação funcional melhor.

este contexto perdedor

Métodos são funções que são armazenadas em objetos. Para que uma função saiba em qual objeto trabalhar, this é usado. this representa o contexto da função.

this perde o contexto em muitas situações. Perde o contexto dentro de funções aninhadas, perde o contexto em retornos de chamada.

Vamos pegar o caso de um objeto timer. Os objetos do temporizador aguardam que a chamada anterior termine antes de fazer uma nova chamada. Ele implementa o padrão recursivo setTimeout. No próximo exemplo , em funções aninhadas e retornos de chamada, this perde o contexto:

 timer de aula { 
construtor (retorno de chamada, intervalo) {
this.callback = retorno de chamada;
this.interval = intervalo;
this.timerId = 0;
}

executeAndStartTimer () {
this .callback (). then (function startNewTimer () {
isso .timerId =
setTimeout ( this .executeAndStartTimer, this .interval);
});
}

começar(){
if (this.timerId === 0) {
this.executeAndStartTimer ();
}
}
 Pare(){ 
if (this.timerId! == 0) {
clearTimeout (this.timerId);
this.timerId = 0;
}
}
}
 const timer = new Timer (getTodos, 2000); 
timer.start ();
 function getTodos () { 
console.log ("chamada");
return fetch (" https://jsonplaceholder.typicode.com/todos ");
}

this perde o contexto quando o método é usado como manipulador de eventos.

Vamos considerar o caso de um componente React que cria uma consulta de pesquisa. Nos dois métodos, usados como manipuladores de eventos, this perde o contexto:

 classe SearchForm estende React.Component { 
handleChange (event) {
const newQuery = Object.freeze ({text: event.target.value});
este .setState (newQuery);
}
 search () { 
const newQuery = Object.freeze ({text: this .state.text});
if ( this .props.onSearch) este .props.onSearch (newQuery);
}
 render () { 
Retorna (
<form>
<input onChange = {this.handleChange} value = {this.state.text} />
<button onClick = {this.search} tipo = "botão"> Pesquisar </ button>
</ form>
);
}
}

Há muitas soluções para esses problemas: o método bind() , o padrão / self, a função de seta.

Para saber mais sobre como corrigir this problemas relacionados a problemas, consulte O que fazer quando “isso” perde o contexto .

isso não tem encapsulamento

this cria problemas de segurança. Todos os membros declarados no this são públicos.

 timer de aula { 
construtor (retorno de chamada, intervalo) {
this.timerId = "secreto";
}
}
 const timer = new Timer (); 
timer.timerId; //segredo

Não, não há protótipos personalizados

E se, em vez de tentar consertar this contexto de perda e problemas de segurança, nos livrarmos de todos juntos?

Remover this tem um conjunto de implicações.

this não significa basicamente nenhuma class , nenhum construtor de função, nenhum new , nenhum Object.create() .

Remover this significa que não há protótipos personalizados em geral.

Uma língua melhor

O JavaScript é uma linguagem de programação funcional e uma linguagem baseada em protótipos. Se nos livrarmos this , ficamos com o JavaScript como uma linguagem de programação funcional. Isso é ainda melhor.

Ao mesmo tempo, sem this , o JavaScript oferece uma maneira nova e única de fazer Programação Orientada a Objetos sem classes e herança.

Programação Orientada a Objetos sem este

As questões são como construir objetos sem this .

Haverá dois tipos de objetos:

  • objetos de dados puros
  • objetos de comportamento

Objetos de dados puros

Objetos de dados puros contêm apenas dados e não possuem comportamento.

Qualquer campo computado será preenchido na criação.

Objetos de dados puros são imutáveis. Precisamos Object.freeze() -los na criação.

Objetos Comportamentais

Objetos de comportamento serão coleções de closures compartilhando o mesmo estado privado.

Vamos criar o objeto Timer em uma abordagem sem this recurso.

 temporizador de função (retorno de chamada, intervalo) { 
let timerId;
 function executeAndStartTimer () { 
callback (). então (função makeNewCall () {
timerId = setTimeout (executeAndStartTimer, interval);
});
}
 function stop () { 
if (timerId) {
clearTimeout (timerId);
timerId = 0;
}
}
 função start () { 
if (! timerId) {
executeAndStartTimer ();
}
}
 return Object.freeze ({ 
começar,
Pare
});
}
 const timer = Timer (getTodos, 2000); 
timer.start ();

O objeto timer possui dois métodos públicos: start e stop . Tudo o resto é privado. Não há this problema de contexto perdedor, pois não existe this .

Componentes sem este

this pode ser exigido pelos frameworks de muitos componentes, como React ou Vue, por exemplo.

No React, podemos criar componentes funcionais sem estado, sem this , como funções puras.

 função ListItem ({todo}) { 
Retorna (
<li>
<div> {todo.title} </ div>
<div> {todo.userName} </ div>
</ li>
);
}

Também podemos criar componentes com estado sem this com React Hooks . Dê uma olhada no próximo exemplo :

 import React, {useState} de "reagir"; 
 function SearchForm ({onSearch}) { 
const [query, setQuery] = useState ({texto: ""});
 function handleChange (event) { 
const newQuery = Object.freeze ({text: event.target.value});
setQuery (newQuery);
}
 pesquisa de função () { 
const newQuery = Object.freeze ({text: query.text});
if (onSearch) onSearch (newQuery);
}
 Retorna ( 
<form>
<input type = "text" onChange = {handleChange} />
<button onClick = {search} tipo = "botão"> Pesquisar </ button>
</ form>
);
};

Removendo Argumentos

Se nos livrarmos this , devemos também nos livrar dos arguments pois eles têm o mesmo comportamento de vinculação dinâmica.

Livrar-se dos arguments é bem simples. Nós apenas usamos a nova sintaxe do parâmetro rest. Desta vez, o parâmetro rest é um objeto de matriz:

 function addNumber (total, valor) { 
retornar total + valor;
}
 função sum ( ... args ) { 
return args.reduce ( addNumber, 0 ) ;
}
 soma (1,2,3); // 6 

Conclusão

A melhor maneira de evitar this problemas relacionados é não usar this .

JavaScript sem this é uma linguagem melhor. E, mais especificamente, JavaScript sem this é uma linguagem de programação funcional melhor.

Podemos construir objetos encapsulados, sem usar this , como coleções de fechamentos.

Com o React Hooks podemos criar this componente sem estados.

Para mais informações sobre o lado funcional do JavaScript, dê uma olhada em:

Descubra a programação funcional em JavaScript com esta introdução completa

Descubra o poder dos closures em JavaScript

Como composição livre de pontos fará de você um melhor programador funcional

Como melhorar seu código com nomes de função que revelam a intenção

Aqui estão alguns decoradores de função que você pode escrever do zero

Torne seu código mais fácil de ler com a programação funcional