A palavra-chave this
refere-se ao valor do objeto vinculado à
função no momento de sua chamada, o que significa que seu valor é diferente dependendo
se uma função é chamada como método, função autônoma ou
construtor.
Quando uma função é chamada, ela cria uma instância da palavra-chave this
atrás
as cenas como referência ao objeto que contém aquela função, concedendo
as propriedades e os métodos definidos junto com ela de dentro do seu escopo.
Trabalhar com this
é, em alguns aspectos, semelhante a trabalhar com uma variável declarada
com const
. Como uma constante, this
não pode ser removida, e o valor dela não pode ser
reatribuído, mas os métodos e propriedades do objeto em que a palavra-chave this
contém podem ser alterados.
Vinculação global
Fora de uma função ou do contexto de um objeto, this
se refere ao
globalThis
, que é uma referência ao objeto global na maioria
ambientes JavaScript. No contexto de um script em execução em um navegador da Web,
o objeto global é o objeto window
:
this;
> Window {0: Window, window: Window, self: Window, document: document, name: '', location: Location, ...}
Em Node.js, globalThis
é o objeto global
:
$ node
Welcome to Node.js v20.10.0.
Type ".help" for more information.
> this
<ref *1> Object [global] {
...
}
Fora do modo estrito, this
também se refere ao objeto global dentro de uma
função, porque o Window
pai é o objeto que efetivamente "possui"
essas funções.
function myFunction() {
console.log( this );
}
myFunction();
> Window {...}
(function() {
console.log( this );
}());
> Window {...}
Ao usar o modo estrito, this
tem um valor de undefined
dentro de uma
função:
(function() {
"use strict";
console.log( this );
}());
> undefined
Antes da introdução do modo estrito, um valor null
ou undefined
para this
é substituída por uma referência ao objeto global. Às vezes, você pode ver
uma vinculação global, conhecida como "vinculação padrão", devido a esse comportamento legado.
Vinculação implícita
Quando uma função é chamada como o método de um objeto, uma instância de this
dentro
o método se refere ao objeto que contém o método, concedendo acesso ao
e as propriedades que acompanham:
let myObject = {
myValue: "This is my string.",
myMethod() {
console.log( this.myValue );
}
};
myObject.myMethod();
> "This is my string."
Pode parecer que o valor de this
depende de como uma função e
objeto em anexo estejam definidos. Em vez disso, o contexto do valor de this
é
o contexto de execução atual. Nesse caso, o contexto de execução é que o
O objeto myObject
está chamando o método myMethod
, então myObject
é o valor
para this
. Isso pode parecer um aspecto técnico no contexto
exemplos, mas para usos mais avançados de this
, é uma distinção essencial para
ter em mente.
Em geral, use this
de maneiras que não esperem que o código circundante tenha
qualquer estrutura específica. A exceção a essa regra é ES5
Funções de seta.
this
nas funções de seta
Em funções de seta,
this
se refere a uma vinculação em uma
ambiente lexicamente incluído. Isso significa que
this
em uma arrow function refere-se ao valor de this
na
contexto mais próximo:
let myObject = {
myMethod() { console.log( this ); },
myArrowFunction: () => console.log( this ),
myEnclosingMethod: function () {
this.myArrowFunction = () => { console.log(this) };
}
};
myObject.myMethod();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }
myObject.myArrowFunction();
> Window {...}
No exemplo anterior, myObject.myMethod()
registra myObject
como o objeto
que “possui” nesse método, mas myObject.myArrowFunction()
retorna globalThis
(ou undefined
), porque a instância de this
dentro da função de seta
em vez disso, refere-se ao mais alto escopo.
No exemplo a seguir, myEnclosingMethod
cria uma função de seta no
que o contém quando executado. A instância de this
dentro
A arrow function agora se refere ao valor de this
ambiente, que é o método que contém essa função de seta. Como o
o valor de this
em myEnclosingMethod
se refere a myObject
, depois que você
definir a função de seta, this
dentro da função de seta também se refere a
myObject
:
let myObject = {
myMethod() { console.log( this ); },
myEnclosingMethod: function () {
this.myArrowFunction = () => { console.log(this) };
}
};
myObject.myEnclosingMethod();
myObject.myArrowFunction();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }
Vinculação explícita
A vinculação implícita processa a maioria dos casos de uso para trabalhar com this
. No entanto,
às vezes pode precisar do valor de this
para representar uma execução específica.
contexto, em vez do contexto presumido. Uma descrição ilustrativa, embora um pouco desatualizada,
exemplo é trabalhar com this
dentro da função de callback de um setTimeout
,
porque esse callback tem um contexto de execução exclusivo:
var myObject = {
myString: "This is my string.",
myMethod() {
console.log( this.myString );
}
};
myObject.myMethod();
> "This is my string."
setTimeout( myObject.myMethod, 100 );
> undefined
Essa falha específica de setTimeout
já foi resolvida por
outros recursos, problemas semelhantes de "perder" this
já foram resolvidas
criando uma referência explícita ao valor de this
no escopo do
contexto pretendido. Talvez você veja instâncias de this
sendo atribuídas
a uma variável usando identificadores como that
, self
ou _this
no
bases de código. Essas são convenções de identificadores comuns para variáveis que contêm
passou o valor this
.
Quando você chama uma função usando os métodos call()
, bind()
ou apply()
,
this
faz referência explícita ao objeto que está sendo chamado:
let myFunction = function() {
console.log( this.myValue );
}
let myObject = {
"myValue" : "This is my string."
};
myFunction.call( myObject );
> "This is my string."
var myObject = {
myString: "This is my string.",
myMethod() {
console.log( this.myString );
}
};
setTimeout( myObject.myMethod.bind( myObject ), 100 );
> "This is my string."
A vinculação explícita substitui o valor de this
fornecido pela vinculação implícita.
let myObject = {
"myValue" : "This string sits alongside myMethod.",
myMethod() {
console.log( this.myValue );
}
};
let myOtherObject = {
"myValue" : "This is a string in another object entirely.",
};
myObject.myMethod.call( myOtherObject );
> "This is a string in another object entirely."
Se uma função for chamada de forma a definir o valor de this
como
undefined
ou null
, esse valor será substituído por globalThis
fora do campo strict
modo:
let myFunction = function() {
console.log( this );
}
myFunction.call( null );
> Window {...}
Da mesma forma, se uma função for chamada de uma forma que daria a this
um primitivo
, esse valor é substituído pelo
objeto wrapper do valor primitivo
fora do modo estrito:
let myFunction = function() {
console.log( this );
}
let myNumber = 10;
myFunction.call( myNumber );
> Number { 10 }
No modo estrito, um valor this
transmitido não é forçado para um objeto.
mesmo que seja um valor primitivo, null
ou undefined
:
"use strict";
let myFunction = function() {
console.log( this );
}
let myNumber = 10;
myFunction.call( myNumber );
> 10
myFunction.call( null );
> null
Vinculação de new
Quando uma class é usada como um construtor usando o
A palavra-chave new
, this
, refere-se à instância recém-criada:
class MyClass {
myString;
constructor() {
this.myString = "My string.";
}
logThis() {
console.log( this );
}
}
const thisClass = new MyClass();
thisClass.logThis();
> Object { myString: "My string." }
Da mesma forma, o valor de this
dentro de uma função construtora chamada usando new
refere-se ao objeto que está sendo criado:
function MyFunction() {
this.myString = "My string.";
this.logThis = function() {
console.log( this );
}
}
const myObject = new MyFunction();
myObject.logThis();
> Object { myString: "My string.", logThis: logThis() }
Vinculação do manipulador de eventos
No contexto de manipuladores de eventos, o valor de this
faz referência ao objeto que
o invoca. Dentro de uma função de callback do manipulador de eventos, isso significa this
.
faz referência ao elemento associado ao gerenciador:
let button = document.querySelector( "button" );
button.addEventListener( "click", function( event ) { console.log( this ); } );
Quando um usuário interage com o button
no snippet anterior, o resultado é
o objeto do elemento que contém o próprio <button>
:
> Button {}
Quando uma arrow function é usada como uma chamada de retorno de listener de eventos, o valor de
this
é fornecido novamente pelo contexto de execução mais próximo. Na parte superior
ou seja, this
dentro de uma função de retorno de chamada do manipulador de eventos
globalThis
(ou undefined
, no modo estrito):
let button = document.querySelector( "button" );
button.addEventListener( "click", ( event ) => { console.log( this ); } );
> undefined
Como acontece com qualquer outro objeto, quando você usa call()
, bind()
ou apply()
métodos para fazer referência à função de callback de um listener de eventos, this
faz referência ao objeto explicitamente:
let button = document.querySelector( "button" );
let myObject = {
"myValue" : true
};
function handleClick() {
console.log( this );
}
button.addEventListener( "click", handleClick.bind( myObject ) );
> Object { myValue: true }
Teste seu conhecimento
No caso de um script executado em um navegador da Web, qual é o objeto global
a que this
se refere quando usado fora de uma função ou do
contexto de um objeto?
window
undefined
browser