aboutsummaryrefslogtreecommitdiff
path: root/files/pt-br/web/javascript/reference/functions/arrow_functions/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'files/pt-br/web/javascript/reference/functions/arrow_functions/index.html')
-rw-r--r--files/pt-br/web/javascript/reference/functions/arrow_functions/index.html384
1 files changed, 384 insertions, 0 deletions
diff --git a/files/pt-br/web/javascript/reference/functions/arrow_functions/index.html b/files/pt-br/web/javascript/reference/functions/arrow_functions/index.html
new file mode 100644
index 0000000000..1694545a71
--- /dev/null
+++ b/files/pt-br/web/javascript/reference/functions/arrow_functions/index.html
@@ -0,0 +1,384 @@
+---
+title: Arrow functions
+slug: Web/JavaScript/Reference/Functions/Arrow_functions
+tags:
+ - ECMAScript 2015
+ - Funções
+ - Intermediário
+ - JavaScript
+ - Referencia
+translation_of: Web/JavaScript/Reference/Functions/Arrow_functions
+---
+<div>{{jsSidebar("Functions")}}</div>
+
+<p>Uma <strong>expressão <em>arrow function</em></strong> possui uma sintaxe mais curta quando comparada a uma expressão de função (<em><a href="/pt-BR/docs/Web/JavaScript/Reference/Operators/function">function expression</a></em>) e não tem seu próprio <em><a href="/pt-BR/docs/Web/JavaScript/Reference/Operators/this">this</a></em>, <em><a href="/pt-BR/docs/Web/JavaScript/Reference/Functions/arguments">arguments</a></em>, <em><a href="/pt-BR/docs/Web/JavaScript/Reference/Operators/super">super</a></em> ou <em><a href="/pt-BR/docs/Web/JavaScript/Reference/Operators/new.target">new.target</a></em>. Estas expressões de funções são melhor aplicadas para funções que não sejam métodos, e elas não podem ser usadas como construtoras (<em>constructors</em>).</p>
+
+<p>{{EmbedInteractiveExample("pages/js/functions-arrow.html")}}</p>
+
+<h2 id="Syntax" name="Syntax">Sintaxe</h2>
+
+<h3 id="Sintaxe_básica">Sintaxe básica</h3>
+
+<pre>(param1, param2, …, paramN) =&gt; { statements }
+(param1, param2, …, paramN) =&gt; expression
+// equivalente a: =&gt; { return expression; }
+
+// Parênteses são opcionais quando só há um nome de parâmetro:
+(singleParam) =&gt; { statements }
+singleParam =&gt; { statements }
+
+// A lista de parâmetros para uma função sem parâmetros deve ser escrita com um par de parênteses.
+() =&gt; { statements }</pre>
+
+<h3 id="Sintaxe_avançada">Sintaxe avançada</h3>
+
+<pre>// Envolva o corpo da função em parênteses para retornar uma expressão literal de objeto:
+params =&gt; ({foo: bar})
+
+// Parâmetros rest (<em><a href="/pt-BR/docs/Web/JavaScript/Reference/Functions/rest_parameters">rest parameters</a>)</em> e parâmetros padrões (<em><a href="/pt-BR/docs/Web/JavaScript/Reference/Functions/Default_parameters">default parameters</a></em>) são suportados
+(param1, param2, ...rest) =&gt; { statements }
+(param1 = defaultValue1, param2, …, paramN = defaultValueN) =&gt; { statements }
+
+// Desestruturação (<em><a href="/pt-BR/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">destructuring</a></em>) dentro da lista de parâmetros também é suportado
+var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) =&gt; a + b + c;
+f(); // 6</pre>
+
+<h2 id="Descrição">Descrição</h2>
+
+<p>Veja também <a href="https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/">"ES6 In Depth: Arrow functions" on hacks.mozilla.org</a>.</p>
+
+<p>Dois fatores influenciaram a introdução das <em>arrow functions</em>: funções mais curtas e a inexistência da palavra chave <code>this</code>.</p>
+
+<h3 id="Funções_mais_curtas">Funções mais curtas</h3>
+
+<pre><code>var elements = [
+ 'Hydrogen',
+ 'Helium',
+ 'Lithium',
+ 'Beryllium'
+];
+
+elements.map(function(element) {
+ return element.length;
+}); // esta sentença retorna o array: [8, 6, 7, 9]
+
+// A função regular acima pode ser escrita como a <em>arrow function</em> abaixo
+elements.map((element) =&gt; {
+ return element.length;
+}); // [8, 6, 7, 9]
+
+// Quando só existe um parâmetro, podemos remover os parênteses envolvendo os parâmetros:
+elements.map(element =&gt; {
+ return element.length;
+}); // [8, 6, 7, 9]
+
+// Quando a única sentença em uma <em>arrow function</em> é `return`, podemos remover `return` e remover
+// as chaves envolvendo a sentença
+elements.map(element =&gt; element.length); // [8, 6, 7, 9]
+
+// Neste caso, porque só precisamos da propriedade <em>length</em>, podemos usar o parâmetro de destruição (<em>destructing parameter</em>):
+// Note que a <em>string</em> `"<em>length</em>"` corresponde a propriedade que queremos obter enquanto que a
+// obviamente propriedade não especial `<em>lengthFooBArX</em>` é só o nome de uma variável que pode ser mudado
+// para qualquer nome válido de variável que você quiser
+elements.map(({ "length": lengthFooBArX }) =&gt; lengthFooBArX); // [8, 6, 7, 9]
+
+// Esta atribuição de parâmetro de destruição (<em>destructing parameter</em>) pode ser escrita como visto abaixo. Entretanto, note que
+// não há um específico `"length"` para selecionar qual propriedade nós queremos obter. Ao invés disso, o nome literal
+// da própria variável `length` é usado como a propriedade que queremos recuperar do objeto.
+elements.map(({ length }) =&gt; length); // [8, 6, 7, 9]</code></pre>
+
+<h3 id="Sem_this_separado">Sem <code>this</code> separado</h3>
+
+<p>Antes das <em>arrow functions</em>, toda nova função definia seu próprio valor de <a href="/pt-BR/docs/Web/JavaScript/Reference/Operators/this">this</a> (baseado em como a função era chamada, um novo objeto no caso de um construtor, <em>undefined</em> em chamadas de funções com modo estrito (<em><a href="/pt-BR/docs/Web/JavaScript/Reference/Strict_mode">strict mode</a>)</em>, o objeto base se a função é chamada como um "método de objeto", etc.). Este comportamento é importuno com um estilo de programação orientado a objeto.</p>
+
+<pre class="brush: js">function Person() {
+ // O contrutor Person() define `<code>this`</code> como uma instância dele mesmo.
+  this.age = 0;
+
+ setInterval(function growUp() {
+ // Em modo não estrito, a função growUp() define `this`
+ // como o objeto global (porque é onde growUp() é executado.),
+  // que é diferente ao `this`
+ // definido pelo construtor Person().
+   this.age++;
+ }, 1000);
+}
+
+var p = new Person();</pre>
+
+<p>No ECMAScript 3/5, este comportamento era corrigido definindo o valor em <code>this</code> à uma variável que pudesse ser encapsulada.</p>
+
+<pre class="brush: js">function Person() {
+ var that = this;
+ that.age = 0;
+
+ setInterval(function growUp() {
+ // A chamada a função refere à variáevel `that` da qual
+ // o valor é o objeto esperado.
+ that.age++;
+ }, 1000);
+}</pre>
+
+<p>Alternativamente, uma função de ligação (<a href="/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">bound function</a>) pode ser criada para que o valor pré-atribuido à <code>this</code> seja passado para a função alvo de ligação (a função <code>growUp()</code> no exemplo acima.</p>
+
+<p>Uma <em>arrow function</em> não tem seu próprio <code>this;</code> o valor <code>this</code> do contexto léxico encapsulado é usado. Ex: <em>Arrow functions</em> seguem as regras normais de pesquisa de variáveis. Então, ao procurar por <code>this</code>, que não está no escopo atual elas acabam encontrando <code>this</code> no escopo encapsulado. Assim, no código a seguir, o <code>this</code> dentro da função que é passado para <code>setInterval</code> tem o mesmo valor do <code>this</code> na função lexicamente encapsulada:</p>
+
+<pre class="brush: js">function Person(){
+ this.age = 0;
+
+ setInterval(() =&gt; {
+ this.age++; // |this| corretamente se refere ao objeto Person
+ }, 1000);
+}
+
+var p = new Person();</pre>
+
+<h4 id="Relação_com_strict_mode">Relação com <em>strict mode</em></h4>
+
+<p>Considerando que <code>this</code> vem do contexto léxico envolvente, as regras do modo estrito (<em><a href="/pt-BR/docs/Web/JavaScript/Reference/Strict_mode">strict mode</a></em>) em relação ao <code>this</code> são ignoradas.</p>
+
+<pre class="brush: js">var f = () =&gt; { 'use strict'; return this };
+f() === window; // ou o objeto global</pre>
+
+<p>O restante das regras do modo estrito (<em>strict mode)</em> são aplicadas normalmente.</p>
+
+<h4 id="Invocação_por_call_ou_apply">Invocação por call ou apply</h4>
+
+<p>Já que as <em>arrow functions</em> não têm o próprio  <code>this</code>, os métodos <code>call()</code> ou <code>apply()</code> só podem passar parâmetros. <code>thisArg</code> é ignorado.</p>
+
+<pre><code>var adder = {
+ base: 1,
+
+ add: function(a) {
+ var f = v =&gt; v + this.base;
+ return f(a);
+ },
+
+ addThruCall: function(a) {
+ var f = v =&gt; v + this.base;
+ var b = {
+ base: 2
+ };
+
+ return f.call(b, a);
+ }
+};
+
+console.log(adder.add(1)); // Deve logar 2
+console.log(adder.addThruCall(1)); // Deve logar 2 ainda</code></pre>
+
+<h3 id="Sem_ligação_(binding)_de_argumentos_(arguments)">Sem ligação (<em>binding</em>) de argumentos (<code><em>arguments</em></code>)</h3>
+
+<p><em>Arrow functions</em> não tem o próprio objeto argumentos (<a href="/pt-BR/docs/Web/JavaScript/Reference/Functions/arguments">arguments object</a>). Assim, neste exemplo, <code>arguments</code> é simplesmente uma referência aos argumentos do escopo encapsulado:</p>
+
+<pre><code>var arguments = [1, 2, 3];
+var arr = () =&gt; arguments[0];
+
+arr(); // 1
+
+function foo(n) {
+ var f = () =&gt; arguments[0] + n; // ligação implícita dos argumentos de foo. arguments[0] é n
+ return f();
+}
+
+foo(3); // 6</code></pre>
+
+<p>Na maioria dos casos, usar parâmetros rest (<em><a href="/pt-BR/docs/Web/JavaScript/Reference/Functions/rest_parameters">rest parameters</a></em>) é uma boa alternativa a usar um objeto <code>arguments</code>.</p>
+
+<pre class="brush: js"><code>function foo(n) {
+ var f = (...args) =&gt; args[0] + n;
+ return f(10);
+}
+
+foo(1); // 11</code></pre>
+
+<h3 id="Arrow_functions_usadas_como_métodos"><em>Arrow functions</em> usadas como métodos</h3>
+
+<p>Como afirmado anteriormente, expressões <em>arrow function</em> são melhores para funções que não sejam métods. Vamos ver o que acontece quando tentamos usá-las como métodos.</p>
+
+<pre><code>'use strict';
+
+var obj = {
+ i: 10,
+ b: () =&gt; console.log(this.i, this),
+ c: function() {
+ console.log(this.i, this);
+ }
+}
+
+obj.b(); // imprime undefined, Window {...} (ou o objeto global)
+obj.c(); // imprime 10, Object {...}</code></pre>
+
+<p><em>Arrow functions</em> não tem o próprio <code>this</code>. Outro exmemplo envolvendo {{jsxref("Object.defineProperty()")}}:</p>
+
+<pre><code>'use strict';
+
+var obj = {
+ a: 10
+};
+
+Object.defineProperty(obj, 'b', {
+ get: () =&gt; {
+ console.log(this.a, typeof this.a, this); // undefined 'undefined' Window {...} (ou o objeto global)
+ return this.a + 10; // representa o objeto global 'Window', portanto 'this.a' retorna 'undefined'
+ }
+});</code></pre>
+
+<h3 id="Uso_do_operador_new">Uso do operador <code>new</code></h3>
+
+<p>Arrow functions não podem ser usadas como construtores e lançarão um erro quando usadas com o <code>new</code>.</p>
+
+<h3 id="Uso_da_propriedade_prototype">Uso da propriedade <code>prototype</code></h3>
+
+<p><em>Arrow functions</em> não têm a propriedade <code>prototype</code>.</p>
+
+<pre><code>var Foo = () =&gt; {};
+console.log(Foo.prototype); // undefined</code></pre>
+
+<h3 id="Uso_da_palavra_chave_yield">Uso da palavra chave <code>yield</code></h3>
+
+<p>A palavra chave <code><a href="/pt-BR/docs/Web/JavaScript/Reference/Operators/yield">yield</a></code> não pode ser usada no corpo de uma <em>arrow function</em> (exceto quando permitido dentro de funções aninhadas dentro delas). como consequência, <em>arrow functions</em> não podem ser usadas como geradoras (<em>generators</em>).</p>
+
+<h2 id="Corpo_de_função">Corpo de função</h2>
+
+<p><em>Arrow functions</em> podem ter um corpo conciso (<em>"concise body")</em> ou o usual corpo em bloco (<em>"block body")</em>.</p>
+
+<p>Em um <em>concise body</em>, apenas uma expressão é especificada, a qual se torna o valor de retorno implícito. Em um <em>block body</em>, você precisa explicitamente usar a declaração de retorno, ou seja, o <code>return</code>.</p>
+
+<pre><code>var func = x =&gt; x * x;
+// sintaxe de concise body. O "return" é implícito
+
+var func = (x, y) =&gt; { return x + y; };
+// Em um função com block body, é necessário um "return" explícito</code></pre>
+
+<h2 id="Retornando_objetos_literais">Retornando objetos literais</h2>
+
+<p>Tenha em mente que retornar objetos literais usando a sintaxe de corpo conciso (<em>concise body</em>) <code>params =&gt; {object:literal}</code> não funcionará como experado.</p>
+
+<pre><code>var func = () =&gt; { foo: 1 };
+// Chamar func() retornará undefined!
+
+var func = () =&gt; { foo: function() {} };
+// SyntaxError (Erro de sintaxe): a declaração da função requer um nome</code></pre>
+
+<p> </p>
+
+<p>Isto acontece porque o código dentro das chaves ({}) é convertido como uma sequência de sentenças (ex: <code>foo</code> é tratado como um título, não como uma chave num objeto literal).</p>
+
+<p>Se lembre de envolver o objeto literal em parênteses.</p>
+
+<pre><code>var func = () =&gt; ({foo: 1});</code>
+</pre>
+
+<h2 id="Quebras_de_linha">Quebras de linha</h2>
+
+<p>Uma <em>arrow function</em> não pode conter uma quebra de linha entre seus parâmetros e sua flecha.</p>
+
+<pre><code>var func = (a, b, c)
+ =&gt; 1;
+// SyntaxError (Erro de sintaxe): experada expressão, mas obteve '=&gt;'</code></pre>
+
+<p>Entretanto, isto pode ser corrigido ao usar parênteses ou colocar a quebra de linha dentro dos argumentos como visto abaixo para garantir que o código permaneça bonito e leve.</p>
+
+<pre class="brush: js"><code>var func = (
+ a,
+ b,
+ c
+) =&gt; (
+ 1
+);
+// SyntaxError (erro de sintaxe) não é lançado</code></pre>
+
+<p> </p>
+
+<h2 id="Ordem_de_análise">Ordem de análise</h2>
+
+<p>Apesar de a flecha numa <em>arrow function</em> não ser um operador, <em>arrow functions</em> possuem regras especiais de análise que interagem diferentemente com precedência de operador (<a href="/pt-BR/docs/Web/JavaScript/Reference/Operators/Operator_Precedence">operator precedence</a>) comparadas à funções comuns.</p>
+
+<pre><code>let callback;
+
+callback = callback || function() {}; // ok
+
+callback = callback || () =&gt; {};
+// SyntaxError (Erro de sintaxe): argumentos inválidos de arrow-function
+
+callback = callback || (() =&gt; {}); // ok</code></pre>
+
+<p> </p>
+
+<h2 id="Mais_exemplos">Mais exemplos</h2>
+
+<pre><code>// Uma arrow function vazia retorna undefined
+let empty = () =&gt; {};
+
+(() =&gt; 'foobar')();
+// Retorna "foobar"
+// (esta é uma Expressão de Função Invocada Imediatamente (Immediately Invoked Function Expression)
+// veja 'IIFE' no glossário)
+
+var simple = a =&gt; a &gt; 15 ? 15 : a;
+simple(16); // 15
+simple(10); // 10
+
+let max = (a, b) =&gt; a &gt; b ? a : b;
+
+// Mapeamento, filtragem, ... simples de array
+
+var arr = [5, 6, 13, 0, 1, 18, 23];
+
+var sum = arr.reduce((a, b) =&gt; a + b);
+// 66
+
+var even = arr.filter(v =&gt; v % 2 == 0);
+// [6, 0, 18]
+
+var double = arr.map(v =&gt; v * 2);
+// [10, 12, 26, 0, 2, 36, 46]
+
+// Cadeias de promessa (<em>promisse chains</em>) mais concisas
+promise.then(a =&gt; {
+ // ...
+}).then(b =&gt; {
+ // ...
+});
+
+// Arrow functions sem parâmetros que são visualmente mais fáceis de analisar
+setTimeout( () =&gt; {
+ console.log('E aconteço antes');
+ setTimeout( () =&gt; {
+ // deeper code
+ console.log('Eu aconteço depois');
+ }, 1);
+}, 1);</code></pre>
+
+<h2 id="Especificações">Especificações</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th scope="col">Especificação</th>
+ <th scope="col">Status</th>
+ <th scope="col">Comentário</th>
+ </tr>
+ <tr>
+ <td>{{SpecName('ES2015', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}</td>
+ <td>{{Spec2('ES2015')}}</td>
+ <td>Definição inicial.</td>
+ </tr>
+ <tr>
+ <td>{{SpecName('ESDraft', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}</td>
+ <td>{{Spec2('ESDraft')}}</td>
+ <td> </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Compatibilidade_com_Navegadores">Compatibilidade com Navegadores</h2>
+
+<div class="hidden">
+<p>A tabela de compatibilidade nesta página é gerada de dados estruturados. Se você quiser contribuir com os dados, por favor verifique <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> e nos mande um <em>pull request</em>.</p>
+</div>
+
+<div>{{Compat("javascript.functions.arrow_functions")}}</div>
+
+<div id="compat-mobile"> </div>