freeCodeCamp/guide/portuguese/javascript/this-reference/index.md

176 lines
6.1 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

---
title: this reference
localeTitle: esta referência
---
## `this` referência
Em JavaScript, cada função tem um `this` de referência criado automaticamente quando você declará-lo. Essa referência é bastante semelhante a `this` referência em outras linguagens baseadas em classes, como Java ou C # (JavaScript é uma linguagem baseada em protótipo e nenhum conceito de "classe"): _Aponta para qual objeto está chamando a função_ (esse objeto às vezes chamado como _contexto_ ). No JavaScript, no entanto, _`this` referência dentro de funções pode ser vinculada a objetos diferentes, dependendo de onde a função está sendo chamada_ . Aqui estão 5 regras básicas para `this` ligação em JavaScript:
### Regra 1
Quando uma função é chamada no escopo global, a referência `this` é, por padrão, vinculada ao **objeto global** ( `window` no navegador ou `global` em Node.js). Por exemplo:
```javascript
function foo() {
this.a = 2;
}
foo();
console.log(a); // 2
```
Nota: Se você declarar a `foo()` função acima no modo estrito, então você chamar essa função no escopo global, `this` será `undefined` e atribuição `this.a = 2` vai jogar `Uncaught TypeError` exceção.
### Regra 2
Vamos examinar o exemplo abaixo:
```javascript
function foo() {
this.a = 2;
}
var obj = {
foo: foo
};
obj.foo();
console.log(obj.a); // 2
```
Claramente, no trecho acima, a função `foo()` está sendo chamada com o _contexto_ `obj` e `this` referência agora está vinculada ao `obj` . Portanto, quando uma função é chamada com um objeto de contexto, a referência `this` será vinculada a esse objeto.
### Regra 3
`.call` , `.apply` e `.bind` podem ser usados no site de chamadas para vincular explicitamente `this` . Usar `.bind(this)` é algo que você pode ver em muitos componentes do React.
```javascript
var foo = function() {
console.log(this.bar)
}
foo.call({ bar: 1 }) // 1
```
Aqui está um exemplo rápido de como cada um é usado para vincular `this` :
* `.call()` : `fn.call(thisObj, fnParam1, fnParam2)`
* `.apply()` : `fn.apply(thisObj, [fnParam1, fnParam2])`
* `.bind()` : `const newFn = fn.bind(thisObj, fnParam1, fnParam2)`
### Regra 4
```javascript
function Point2D(x, y) {
this.x = x;
this.y = y;
}
var p1 = new Point2D(1, 2);
console.log(p1.x); // 1
console.log(p1.y); // 2
```
A coisa que você deve notar é que a função `Point2D` é chamada com a `new` palavra-chave, e `this` referência está vinculada ao objeto `p1` . Portanto, quando uma função é chamada com uma `new` palavra-chave, ela criará um novo objeto e `this` referência será vinculada a esse objeto.
Nota: Como você chama uma função com uma `new` palavra-chave, também a chamamos como _função construtora_ .
### Regra 5
JavaScript determina o valor `this` em tempo de execução, com base no contexto atual. Então, `this` às vezes pode apontar para algo diferente do que você espera.
Considere este exemplo de uma classe Cat com um método chamado `makeSound()` , seguindo o padrão da Regra 4 (acima) com uma função construtora e a `new` palavra-chave.
```javascript
var Cat = function(name, sound) {
this.name = name;
this.sound = sound;
this.makeSound = function() {
console.log( this.name + ' says: ' + this.sound );
};
}
var kitty = new Cat('Fat Daddy', 'Mrrooowww');
kitty.makeSound(); // Fat Daddy says: Mrrooowww
```
Agora vamos tentar dar ao gato uma maneira de `annoy()` pessoas repetindo seu som 100 vezes, uma vez a cada meio segundo.
```javascript
var Cat = function(name, sound) {
this.name = name;
this.sound = sound;
this.makeSound = function() {
console.log( this.name + ' says: ' + this.sound );
};
this.annoy = function() {
var count = 0, max = 100;
var t = setInterval(function() {
this.makeSound(); // <-- this line fails with `this.makeSound is not a function`
count++;
if (count === max) {
clearTimeout(t);
}
}, 500);
};
}
var kitty = new Cat('Fat Daddy', 'Mrrooowww');
kitty.annoy();
```
Isso não funciona porque dentro do callback `setInterval` nós criamos um novo contexto com escopo global, então `this` não aponta mais para a nossa instância do kitty. Em um navegador da Web, `this` indicará o objeto Window, que não possui um método `makeSound()` .
Algumas maneiras de fazer isso funcionar:
1) Antes de criar o novo contexto, atribua `this` a uma variável local chamada `me` , `self` , ou o que você quiser chamá-lo, e use essa variável dentro do callback.
```javascript
var Cat = function(name, sound) {
this.name = name;
this.sound = sound;
this.makeSound = function() {
console.log( this.name + ' says: ' + this.sound );
};
this.annoy = function() {
var count = 0, max = 100;
var self = this;
var t = setInterval(function() {
self.makeSound();
count++;
if (count === max) {
clearTimeout(t);
}
}, 500);
};
}
var kitty = new Cat('Fat Daddy', 'Mrrooowww');
kitty.annoy();
```
2) Com ES6 você pode evitar atribuir `this` a uma variável local usando uma função de seta, que liga `this` ao contexto do código circundante onde ele está definido.
```javascript
var Cat = function(name, sound) {
this.name = name;
this.sound = sound;
this.makeSound = function() {
console.log( this.name + ' says: ' + this.sound );
};
this.annoy = function() {
var count = 0, max = 100;
var t = setInterval(() => {
this.makeSound();
count++;
if (count === max) {
clearTimeout(t);
}
}, 500);
};
}
var kitty = new Cat('Fat Daddy', 'Mrrooowww');
kitty.annoy();
```
### Outros recursos
* [javascriptissexy.com](http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/)
* [Você não sabe JS](https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch2.md)