diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
commit | 074785cea106179cb3305637055ab0a009ca74f2 (patch) | |
tree | e6ae371cccd642aa2b67f39752a2cdf1fd4eb040 /files/pt-br/web/javascript/reference/operators/this | |
parent | da78a9e329e272dedb2400b79a3bdeebff387d47 (diff) | |
download | translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.gz translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.bz2 translated-content-074785cea106179cb3305637055ab0a009ca74f2.zip |
initial commit
Diffstat (limited to 'files/pt-br/web/javascript/reference/operators/this')
-rw-r--r-- | files/pt-br/web/javascript/reference/operators/this/index.html | 410 |
1 files changed, 410 insertions, 0 deletions
diff --git a/files/pt-br/web/javascript/reference/operators/this/index.html b/files/pt-br/web/javascript/reference/operators/this/index.html new file mode 100644 index 0000000000..dc1798e093 --- /dev/null +++ b/files/pt-br/web/javascript/reference/operators/this/index.html @@ -0,0 +1,410 @@ +--- +title: this +slug: Web/JavaScript/Reference/Operators/this +tags: + - Expressões Primárias + - JavaScript + - Operador + - Referencia +translation_of: Web/JavaScript/Reference/Operators/this +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>A palavra-chave <strong><code>this</code></strong> comporta-se um pouco diferente em Javascript se comparado com outras linguagens. Também possui algumas diferenças entre o <a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Funciones/Modo_estricto" title="en-US/docs/JavaScript/Strict mode">modo estrito</a> e o modo não estrito.</p> + +<p>Em muitos casos, o valor <code>this</code> é determinado pela forma como a função é chamada. Ele não pode ser assinado durante a execução, e isso pode ser diferente a cada vez que a função é chamada. ES5 introduziu o método <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">bind</a></code> para estabelecer o valor <code>this</code> da função, independentemente de como ela seja chamada, e ECMAScript 2015 introduziu o <a href="../Functions/Arrow_functions">arrow functions</a>, cujo <code>this</code> é lexicalmente delimitado (o valor <code>this</code> é estabelecido segundo o escopo de execução no qual está inserido).</p> + +<h2 id="Sintaxe">Sintaxe</h2> + +<pre class="syntaxbox">this</pre> + +<h2 id="Contexto_global">Contexto global</h2> + +<p>No contexto de execução global (fora de qualquer função), <code>this</code> refere-se ao objeto global, seja em modo estrito ou não.</p> + +<pre class="brush:js">console.log(this.document === document); // true + +// Em navegadores web, o objeto window é também o objeto global: +console.log(this === window); // true + +this.a = 37; +console.log(window.a); // 37 +</pre> + +<h2 id="Contexto_de_função">Contexto de função</h2> + +<p>Dentro de uma função, o valor de <code>this</code> depende de como a função é chamada.</p> + +<h3 id="Chamada_simples">Chamada simples</h3> + +<p>Como o código a seguir não está no modo estrito, o valor de <code>this</code> não é definido pela chamada. Por padrão, <code>this</code> será o objeto global que no navegador é o <code>window</code>.</p> + +<pre class="brush: js">function f1(){ + return this; +} + +// No navegador +f1() === window; // true +</pre> + +<p>Em modo estrito, o valor de <code>this</code> permanece seja qual for o definido ao entrar no contexto de execução, assim, no caso a seguir, <code>this</code> por padrão será indefinido (<code>undefined</code>):</p> + +<pre class="brush:js">function f2(){ + "use strict"; // assume modo estrito + return this; +} + +f2() === undefined; // true +</pre> + +<p>Portanto, em modo estrito, se <code>this</code> não for definido durante o contexto da execução, ele permanecerá indefinido (<code>undefined</code>).</p> + +<div class="note">No segundo exemplo, <code>this</code> deveria ser <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined"><code>undefined</code></a>, porque <code>f2</code> foi chamada diretamente e não como um método ou popriedade de um objeto (ou seja, <code>window.f2()</code>). Esta característica não foi implementada em alguns navegadores quando começaram a dar suporte ao <a href="/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode" title="Strict mode">strict mode</a> (modo estrito). Como resultado, eles incorretamente retornavam o objeto <code>window</code>.</div> + +<p> </p> + +<h3 id="Funções_Arrow_(seta)">Funções Arrow (seta)</h3> + +<p>Nas <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">arrow functions</a> (funções seta), o <code>this</code> é definido lexicalmente, isto é, seu valor é definido pelo contexto de execução onde está inserido. Em um código global, this assume o objeto global:</p> + +<pre class="brush: js">var globalObject = this; +var foo = (() => this); +console.log(foo() === globalObject); // true</pre> + +<p>Não importa como <code>foo</code> é chamado, o <code>this</code> continuará como o objeto global. Isto continua verdadeiro mesmo se chamá-lo como método de um determinado objeto (o que normalmente definiria seu this ao objeto), com <code>call</code> ou <code>apply</code> ou <code>bind</code> é usado:</p> + +<pre class="brush: js">// Chama como um método de um objeto +var obj = {foo: foo}; +console.log(obj.foo() === globalObject); // true + +// Tentativa de definir this usando call +console.log(foo.call(obj) === globalObject); // true + +// Tentantiva de definir this usando bind +foo = foo.bind(obj); +console.log(foo() === globalObject); // true</pre> + +<p>Não importa como for, o this do foo mantém o valor que recebeu quando foi criado (no exemplo acima, o objeto global). O mesmo se aplica para funções arrow criadas dentro de outras funções: seus this são definidos em seus respectivos contextos de execução.</p> + +<pre class="brush: js">// Cria obj com um método bar que retorna uma função que +// retorna seu this. A função retornada é criada como +// uma função arrow, para que seu this esteja permanentemente +// ligado ao this da função que a envolve. O valor de bar pode ser // definido na chamada, que por sua vez define o valor da função +// retornada. +var obj = { bar : function() { + var x = (() => this); + return x; + } + }; + +// Chama bar como método de obj, configurando seu this como obj +// Assina à variável fn uma referência para a função retornada +var fn = obj.bar(); + +// Chamar fn, sem definir this, por padrão, referenciaria +// ao objeto global ou undefined em modo estrito (strict mode) +console.log(fn() === obj); // true</pre> + +<p>No exemplo acima, a função (chamemos função anônima A) atribuída a obj.bar retorna outra função (chamemos função anônima B) que é criada como uma função arrow (seta). Como resultado, o this da função B é permanentemente definido como o this de obj.bar (função A) quando chamado. Quando a função retornada (função B) é chamada, seu this sempre será aquele que foi definido inicialmente. No exemplo de código acima, o this da função B é definido com o this da função A, que é obj, por isso permanece definido para obj, mesmo quando chamado de uma maneira que normalmente definiria seu this como undefined ou como objeto global (ou qualquer outro método, como naquele exemplo anterior de contexto de execução global).</p> + +<h3 id="Como_método_de_um_objeto">Como método de um objeto</h3> + +<p>Quando uma função é chamada como um método de um objeto, seu this toma o valor do objeto pertencente ao método chamado.</p> + +<p>No exemplo a seguir, quando <code>o.f()</code> é invocado, o this dentro da função é vinculado ao objeto o.</p> + +<pre class="brush:js">var o = { + prop: 37, + f: function() { + return this.prop; + } +}; + +console.log(o.f()); // logs 37 +</pre> + +<p>Observe que esse comportamento não é afetado mesmo pela forma como (ou onde) a função foi definida. No exemplo anterior, nós definimos a função in-line (em linha) como o membro f durante a definição de o. No entanto, poderíamos ter apenas facilmente definido a função primeiro e depois anexado a o.f. Fazendo isso resulta no mesmo comportamento:</p> + +<pre class="brush:js">var o = {prop: 37}; + +function independent() { + return this.prop; +} + +o.f = independent; + +console.log(o.f()); // registra 37 +</pre> + +<p>Isto demonstra que é importante apenas que a função foi chamada a partir do membro f de o.</p> + +<p>Da mesma forma, a vinculação de this só é afetada pela referência do membro mais imediato. No exemplo a seguir, quando invocamos a função, podemos chamá-la como um método g do objeto o.b. Desta vez, durante a execução, o this dentro da função irá se referir a o.b. O fato do objeto ser um membro de o não tem qualquer consequência; a referência mais imediata é tudo que importa.</p> + +<pre class="brush:js">o.b = {g: independent, prop: 42}; +console.log(o.b.g()); // registra 42 +</pre> + +<h4 id="this_na_cadeia_de_protótipos_(prototype_chain)_do_objeto"><code>this</code> na cadeia de protótipos (prototype chain) do objeto</h4> + +<p>A mesma noção vale para métodos definidos em algum lugar da cadeia de protótipos do objeto. Se o método está na cadeia de protótipo de um objeto, this refere-se ao objeto que é proprietário do método chamado, como se o método estivesse no objeto.</p> + +<pre class="brush:js">var o = {f:function(){ return this.a + this.b; }}; +var p = Object.create(o); +p.a = 1; +p.b = 4; + +console.log(p.f()); // 5 +</pre> + +<p>Neste exemplo, o objeto atribuído à variável p não tem sua própria propriedade f, ele o herda de seu protótipo. Mas não importa que a procura por f finalmente encontre um membro com esse nome em o; a procura começou como uma referência para a p.f, portanto o this dentro da função recebe o valor do objeto referido como p. Isto é, já que f é chamado como um método de p, seu this refere-se a p. Este é um recurso interessante de herança prototípica do JavaScript.</p> + +<h4 id="this_com_seletores_(getter)_ou_modificadores_(setter)"><code>this</code> com seletores (getter) ou modificadores (setter) </h4> + +<p>Mais uma vez, a mesma noção se aplica quando uma função é chamada a partir de um getter ou setter. A função usada como getter ou setter tem seu this ligado ao objeto do qual a propriedade está sendo modificada ou selecionada.</p> + +<pre class="brush:js">function modulus(){ + return Math.sqrt(this.re * this.re + this.im * this.im); +} + +var o = { + re: 1, + im: -1, + get phase(){ + return Math.atan2(this.im, this.re); + } +}; + +Object.defineProperty(o, 'modulus', { + get: modulus, enumerable:true, configurable:true}); + +console.log(o.phase, o.modulus); // logs -0.78 1.4142 +</pre> + +<h3 id="Como_um_construtor_(constructor)">Como um construtor (constructor)</h3> + +<p>Quando a função é usada com um construtor (com a palavra chave <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/new">new</a></code>), seu this é vinculado ao novo objeto sendo contruído.</p> + +<p>Nota: enquanto o padrão para um construtor é retornar o objeto referenciado por this, ele pode retornar, ao invés, algum outro objeto (se o valor de retorno não é um objeto, então o objeto this é retornado).</p> + +<pre class="brush:js">/* + * Contrutores funcionam da seguinte forma: + * + * function MyConstructor(){ + * // O código do corpo da função vai aqui. + * // Criam-se propriedades sobre |this| como + * // desejado, assinando-os. Ex., + * this.fum = "nom"; + * // etc... + * + * // Se a função tem uma instrução que + * // retorna um objeto, esse objeto será o + * // resultado da expressão |new|. Caso contrário, + * // o resultado da expressão é o objeto + * // atualmente vinculado a |this| + * // (i.e., o caso mais comumente visto). + * } + */ + +function C(){ + this.a = 37; +} + +var o = new C(); +console.log(o.a); // logs 37 + + +function C2(){ + this.a = 37; + return {a:38}; +} + +o = new C2(); +console.log(o.a); // registra 38 +</pre> + +<p>No último exemplo (C2), porque um objeto foi retornado durante a construção, o novo objeto que this foi vinculado simplesmente é descartado. (Isso essencialmente faz da expressão "this.a = 37;" código morto. Não é exatamente morto, pois ele é executado, mas ele pode ser eliminado sem efeitos colaterais.)</p> + +<h3 id="call_e_apply"><code>call</code> e <code>apply</code></h3> + +<p>Quando uma função usa a palavra-chave this em seu corpo, o seu valor pode ser vinculado a um determinado objeto na chamada utilizando os métodos <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call">call</a></code> or <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply">apply</a></code> que todas as funções herdam de Function.prototype.</p> + +<pre class="brush:js">function add(c, d){ + return this.a + this.b + c + d; +} + +var o = {a:1, b:3}; + +// O primeiro parâmetro é o objeto a usar como +// 'this'; subsequentes parâmetros são passados como +// argumentos na função chamada +add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16 + +// O primeiro parâmetro é o objeto a usar como +// 'this', o segundo é um arranjo (array) cujos +// membros são usados como argumentos na função chamada +add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34 +</pre> + +<p>Observe que, com call e apply, se o valor passado como this não for um objeto, será feita uma tentativa de convertê-lo em um objeto usando a operação interna ToObject. Portanto, se o valor passado é um primitivo como 7 ou 'foo', ele será convertido para um objeto usando o construtor relacionado, de modo que o número primitivo 7 é convertido em um objeto, como realizado por new Number(7), e a cadeia de caracteres 'foo' em um objeto, como realizado por new String(' foo '), por exemplo.</p> + +<pre class="brush:js">function bar() { + console.log(Object.prototype.toString.call(this)); +} + +bar.call(7); // [object Number] +</pre> + +<h3 id="O_método_bind">O método <code>bind</code></h3> + +<p>ECMAScript 5 introduziu <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">Function.prototype.bind</a></code>. Chamando f.bind(algumObjeto) cria-se uma nova função com o mesmo corpo e escopo que f, mas onde o this ocorrer na função original, na nova função ele será permanentemente ligado ao primeiro argumento de bind, independentemente de como a função esteja sendo usada.</p> + +<pre class="brush:js">function f(){ + return this.a; +} + +var g = f.bind({a:"azerty"}); +console.log(g()); // azerty + +var h = g.bind({a: 'yoo'}); // bind só funciona uma vez! +console.log.(h()); // azerty + +var o = {a:37, f:f, g:g, h: h}; +console.log(o.a, o.f(), o.g(), o.h()); // 37, 37, azerty, azerty +</pre> + +<h3 id="Como_um_manipulador_de_eventos_DOM">Como um manipulador de eventos DOM</h3> + +<p>Quando uma função é usada como um manipulador de eventos, seu this está definido para o elemento do evento a partir do qual foi disparado (alguns navegadores não seguem essa convenção para os listeners adicionados dinamicamente com métodos que não sejam addEventListener).</p> + +<pre class="brush:js">// Quando chamado como listener, transforma o elemento blue +// relacionado +function bluify(e){ + // sempre true + console.log(this === e.currentTarget); + // true quando currentTarget e target são o mesmo objeto + console.log(this === e.target); + this.style.backgroundColor = '#A5D9F3'; +} + +// Obtém uma lista de todo elemento no documento +var elements = document.getElementsByTagName('*'); + +// Adiciona bluify com um click listener (escutador de click) +// para que quando o elemento seja clicado se torne azul +for(var i=0 ; i<elements.length ; i++){ + elements[i].addEventListener('click', bluify, false); +}</pre> + +<h3 id="Em_um_manipulador_de_evento_in-line_(em_linha)">Em um manipulador de evento in-line (em linha)</h3> + +<p>Quando o código é chamado de um manipulador de evento in-line, seu this está definido para o elemento DOM em que o listener é colocado:</p> + +<pre class="brush:js"><button onclick="alert(this.tagName.toLowerCase());"> + Show this +</button> +</pre> + +<p>O alerta acima mostra button. Note, porém, que apenas o código exterior tem um this definido desta maneira:</p> + +<pre class="brush:js"><button onclick="alert((function(){return this}()));"> + Show inner this +</button> +</pre> + +<p>Neste caso, o this da função interior não está definido, portanto ele retorna o objeto global/objeto window (ou seja, o objeto padrão no modo não-estrito onde this não está definido pela chamada).</p> + +<h2 id="Especificações">Especificações</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Especificação</th> + <th scope="col">Estado</th> + <th scope="col">Comentário</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-this-keyword', 'The this keyword')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-this-keyword', 'The this keyword')}}</td> + <td>{{Spec2('ES6')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.1.1', 'The this keyword')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES3', '#sec-11.1.1', 'The this keyword')}}</td> + <td>{{Spec2('ES3')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES1', '#sec-11.1.1', 'The this keyword')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Initial definition. Implemented in JavaScript 1.0.</td> + </tr> + </tbody> +</table> + +<h2 id="Compatibilidade_com_navegadores">Compatibilidade com navegadores</h2> + +<p>{{CompatibilityTable}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="Veja_também">Veja também</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode">Strict mode</a></li> + <li><a href="http://bjorn.tipling.com/all-this">All this</a>, um artigo sobre this em diferentes contextos</li> +</ul> |