"this" é uma referência de contexto
A palavra reservada this é uma referência de contexto.
Na maioria dos casos, o valor de this é determinado por como uma função é chamada (runtime binding).
Não pode ser definido por atribuição durante a execução e pode ser diferente cada vez que a função é chamada.
Valor: Uma propriedade de um contexto de execução (global, função ou eval) que, no modo não estrito, é sempre uma referência a um objeto e no modo estrito pode ser qualquer valor.
- NOTES:
- Existem algumas diferenças entre o modo strict e o modo non-strict.
- O ES5 introduziu o método bind() para definir o valor de uma função com this independentemente de como é chamado.
- O ES2015 introduziu arrow functions que não fornecem sua própria this binding (retém o this valor do enclosing lexical context).
Tabela de Contexto X Referências
Contexto | Referência |
---|---|
Método de um objeto | Próprio objeto dono do método |
Sozinha | Contexto global (em navegadores, window) |
Função | Contexto global |
Evento | Elemento que recebeu o evento |
Método de um Objeto
const person = {
id: 1,
firstName: 'John',
lastName: 'Doe',
age: 30,
fullName: function() {
return this.firstName + ' ' + this.lastName;
},
getId: function() {
return this.id;
}
}
Navegador
No contexto de execução global (fora de qualquer função), this refere-se ao objeto global, seja em modo estrito ou não.In web browsers, the window object is also the global object:
console.log(this); // Window {window: Window, ...}
console.log(this === window); // true
a = 37;
console.log(window.a); // 37
this.b = "MDN";
console.log(window.b) // "MDN"
console.log(b) // "MDN"
var name = 'teste';
console.log(this.name); // teste
Contexto de Função
Dentro de uma função, o valor de this depende de como a função é chamada.Exemplo, this refere-se ao objeto global, porque o valor de this está definido pela chamada:
// Modo non-strict
function f1() {
return this;
}
// In a browser:
f1() === window; // true
// In Node:
f1() === globalThis; // true
// Node: Object [global]
// Browser: Window
(function(){ console.log(this)})();
// Modo strict
function f2() {
'use strict';
return this;
}
f2(); // undefined
No modo strict, o valor de this é undefined, pois a função f2() foi chamada diretamente e não como método ou propriedade de um objeto (ex: window.f2()).Para definir o valor de this para um valor específico ao chamar uma função, use call() ou apply().
Exemplo, this refere-se ao objeto chamador, contexto de execução da função:
let user = {
name: "Heviane",
getName: function() { console.log( this.name ); }
};
user.getName(); // Heviane
Contexto de Arrow Functions
this retém o valor do contexto léxico envolvente this.No código global, será definido para o objeto global:
var globalObject = this;
var foo = (() => this);
console.log(foo() === globalObject); // true
DOM Event Handler
Inline Event Handler
When the code is called from an inline on-event handler, its this is set to the DOM element on which the listener is placed: Quando o código é chamado de um manipulador de evento embutido, this é definido para o elemento DOM no qual o ouvinte é colocado.O alerta acima mostra button.
Na função interna, this não está definida, então retorna o objeto global, que no navegador é window (ou seja, o objeto padrão no modo no-strict onde this não está definido pelo chamador).
// Evento de um elemento...Falta testar...
const button = document.querySelector('button');
button.addEventListener('click', function() {
console.log(this); // button
});
Classes
Assim como em regular functions, o valor do this é definido pela chamada (contexto de execução da classe).Às vezes é útil substituir esse comportamento para que this dentro da classe sempre se refira à instância da classe. Para fazer isso use o método bind() no construtor da classe.
class Car {
constructor() {
// Bind sayBye but not sayHi to show the difference
this.sayBye = this.sayBye.bind(this);
}
sayHi() {
console.log(`Hello from ${this.name}`);
}
sayBye() {
console.log(`Bye from ${this.name}`);
}
get name() {
return 'Ferrari';
}
}
class Bird {
get name() {
return 'Tweety';
}
}
const car = new Car();
const bird = new Bird();
// The value of 'this' in methods depends on their caller
car.sayHi(); // Hello from Ferrari
bird.sayHi = car.sayHi;
bird.sayHi(); // Hello from Tweety
// For bound methods, 'this' doesn't depend on the caller
bird.sayBye = car.sayBye;
bird.sayBye(); // Bye from Ferrari
Classes sempre são em modo strict. Chamar métodos com um this indefinido irá gerar um erro.
Nota: Você sempre pode obter facilmente o objeto global usando a globalThis propriedade global, independentemente do contexto atual em que seu código está sendo executado.
// Browser
console.log(globalThis); // Window {window: Window, ...}
// Terminal
console.log(globalThis); // Object [global]