Desmistificando o 'this' em JavaScript: Um Olhar Crítico sobre o Escopo de Execução

A forma como o this é tratado em JavaScript pode gerar confusão, especialmente para iniciantes. Uma afirmação comum em alguns materiais didáticos, como "this é o escopo em que a função está sendo executada", é imprecisa e pode levar a interpretações errôneas. É crucial distinguir entre o escopo de definição de uma função e o escopo em que ela é invocada.

Considere o seguinte cenário:


function outerFunction() {
 // ...
}

function middleFunction() {
 /// ...

 return function innerFunction() {
   // ...
 };
}

var immediateCall = middleFunction();
outerFunction();
immediateCall();
 

Neste exemplo, outerFunction, middleFunction e immediateCall (que é innerFunction) são invocadas no escopo global. Portanto, outerFunction e middleFunction executam em um contexto global. Contudo, immediateCall é executada dentro do escopo de middleFunction, não no escopo global. Se innerFunction fizesse referência a this, e considerando a afirmação original, isso implicaria que innerFunction estaria rodando no escopo global, o que contradiz o fato de ela ter sido definida dentro de middleFunction.

Um exemplo mais expplícito demonstra essa distinção:


var globalMessage = 'Olá, escopo global!';

function displayMessage() {
 console.log(globalMessage);
 console.log(this.globalMessage);
}

var person = {
 globalMessage:'Olá, de Pessoas!'
};
person.display = displayMessage;
person.display();
 

Neste caso, this dentro de displayMessage aponta para person. Se a afirmação de que this representa o escopo de execução fosse verdadeira, então displayMessage estaria sendo executada no contexto de person. Isso significaria que a resolução do nome globalMessage dentro da função começaria por person, resultando em ambas as saídas sendo "Olá, de Pessoas!". Como isso não ocorre na prática, a premissa original é invalidada.

Para evitar confusão, a compreensão do this em JavaScript deve focar nos seguintes pontos:

  1. Quando uma função é chamada como um método de um objeto, this (dentro da função, excluindo funções aninhadas) refere-se a esse objeto.
  2. Ao invocar uma função construtora com o operador new, um novo objeto é criado e a função construtora é executada nesse objeto. Nesse cenário, this dentro do construtor aponta para esse novo objeto.
  3. Uma chamada de função direta é tratada como uma invocação de método do objeto global.
  4. Como JavaScript não possui escopo de classe no sentido tradicional, o acesso a propriedades do objeto que invocou um método é feito através de this.propertyName.

Adicionalmente, a resolução de nomes em JavaScript é importante. Nomes referenciados diretamente são resolvidos na cadeia de escopos da função. Em contrapartida, nomes acessados via objeto.propriedade são resolvidos na cadeia de protótipos do objeto (primeiro no próprio objeto e depois em seus protótipos).

Tags: javascript this escopo resolução de nomes funções

Publicado em 7-7 20:49