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

176 lines
6.1 KiB
Markdown
Raw Normal View History

---
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)