aboutsummaryrefslogtreecommitdiff
path: root/files/pt-br/web/javascript/guide/iterators_and_generators
diff options
context:
space:
mode:
authorFlorian Merz <me@fiji-flo.de>2021-02-11 14:49:58 +0100
committerFlorian Merz <me@fiji-flo.de>2021-02-11 14:49:58 +0100
commit68fc8e96a9629e73469ed457abd955e548ec670c (patch)
tree8529ab9fe63d011f23c7f22ab5a4a1c5563fcaa4 /files/pt-br/web/javascript/guide/iterators_and_generators
parent8260a606c143e6b55a467edf017a56bdcd6cba7e (diff)
downloadtranslated-content-68fc8e96a9629e73469ed457abd955e548ec670c.tar.gz
translated-content-68fc8e96a9629e73469ed457abd955e548ec670c.tar.bz2
translated-content-68fc8e96a9629e73469ed457abd955e548ec670c.zip
unslug pt-br: move
Diffstat (limited to 'files/pt-br/web/javascript/guide/iterators_and_generators')
-rw-r--r--files/pt-br/web/javascript/guide/iterators_and_generators/index.html161
1 files changed, 161 insertions, 0 deletions
diff --git a/files/pt-br/web/javascript/guide/iterators_and_generators/index.html b/files/pt-br/web/javascript/guide/iterators_and_generators/index.html
new file mode 100644
index 0000000000..13a9b87f11
--- /dev/null
+++ b/files/pt-br/web/javascript/guide/iterators_and_generators/index.html
@@ -0,0 +1,161 @@
+---
+title: Iteratores e geradores
+slug: Web/JavaScript/Guide/Iteratores_e_geradores
+tags:
+ - Generators
+ - Guia(2)
+ - Intermediario(2)
+ - Iteradores
+ - JavaScript
+translation_of: Web/JavaScript/Guide/Iterators_and_Generators
+---
+<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Meta_programming")}}</div>
+
+<p class="summary">Processar cada item em uma coleção é uma operação muito comum. O JavaScript disponibiliza uma série de maneiras de iterar sobre uma coleção, desde um simples laço {{jsxref("Statements/for","for")}}, até um {{jsxref("Global_Objects/Array/map","map()")}} e também com o {{jsxref("Global_Objects/Array/filter","filter()")}}. Iteradores e Geradores trazem o conceito da interação ocorrer diretamente no núcleo da linguagem e prover um mecanismo para a customização do comportamento dos laços {{jsxref("Statements/for...of","for...of")}}.</p>
+
+<p>Para detalhes, também veja:</p>
+
+<ul>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Iteration_protocols">Protocolos de iteração</a></li>
+ <li>{{jsxref("Statements/for...of","for...of")}}</li>
+ <li>{{jsxref("Statements/function*","function*")}} e {{jsxref("Generator")}}</li>
+ <li>{{jsxref("Operators/yield","yield")}} e {{jsxref("Operators/yield*","yield*")}}</li>
+</ul>
+
+<h2 id="Iterators_Iteradores">Iterators (Iteradores)</h2>
+
+<p>Um objeto é um <strong>iterator (iterador)</strong> quando sabe como acessar itens numa coleção, um por vez, enquanto mantém rastreada a posição atual em uma dada sequência. Em JavaScript um iterator é um objeto que oferece o método <code>next(),</code> o qual retorna o próximo item da sequência. Este método retorna um objeto com duas propriedades: <code>done</code> e <code>value</code>.</p>
+
+<p>Uma vez criado, um objeto iterator pode ser usado explicitamente ao chamar repetidas vezes o método <code>next()</code>.</p>
+
+<pre class="brush: js notranslate">const makeIterator = (array) =&gt; {
+
+let nextIndex = 0;
+
+return {
+ next : () =&gt; {
+ return nextIndex &lt; array.length ?
+ {value: array[nextIndex ++], done: false} :
+ {done: true};
+ }
+ }
+};</pre>
+
+<p>Uma vez inicializado, o método <code>next()</code> pode ser chamado para acessar os pares chave/valor do objeto da vez.</p>
+
+<pre class="brush: js notranslate">let it = makeIterator(['yo', 'ya']);
+console.log(it.next().value); // 'yo'
+console.log(it.next().value); // 'ya'
+console.log(it.next().done); // true</pre>
+
+<h2 id="Iterables_Iteráveis">Iterables (Iteráveis)</h2>
+
+<p>Um objeto é iterável <strong>(iterable),</strong> se ele define seu comportamento de iteração, como no caso de quais valores percorridos em um laço do tipo {{jsxref("Statements/for...of", "for..of")}}. Alguns tipos embutidos, como o {{jsxref("Array")}}, ou o {{jsxref("Map")}}, têm um comportamento iterável padrão, enquanto outros tipos (como o{{jsxref("Object")}}) não possuem.</p>
+
+<p>Para que um objeto seja <strong>iterable</strong>, o objeto precisa implemntar o método <strong>@@iterator</strong>, significando que o objeto (ou um dos objetos na cadeia de prototipagem  - <a href="/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain">prototype chain</a>) precisa ter uma propriedade com uma chave {{jsxref("Symbol.iterator")}}:</p>
+
+<h3 id="Iterables_definidos_pelo_usuário">Iterables definidos pelo usuário</h3>
+
+<p>Nós podemos fazer, criar, os nossos próprios iteráveis como aqui:</p>
+
+<pre class="brush: js notranslate">var myIterable = {}
+myIterable[Symbol.iterator] = function* () {
+    yield 1;
+    yield 2;
+    yield 3;
+};
+[...myIterable] // [1, 2, 3]
+</pre>
+
+<h3 id="Iterables_Built-in_Iteráveis_Embutidos">Iterables Built-in (Iteráveis Embutidos)</h3>
+
+<p>{{jsxref("String")}}, {{jsxref("Array")}}, {{jsxref("TypedArray")}}, {{jsxref("Map")}} e {{jsxref("Set")}} são iteráveis embutidos, pois o protótipo dos objetos de todos eles têm o método {{jsxref("Symbol.iterator")}}.</p>
+
+<h3 id="Syntaxes_expecting_iterables">Syntaxes expecting iterables</h3>
+
+<p>Algumas declarações e expressões esperam por iteradores, por exemplo o {{jsxref("Statements/for...of","for-of")}} loops, {{jsxref("Operators/Spread_operator","spread operator","","true")}}, {{jsxref("Operators/yield*","yield*")}}, e {{jsxref("Operators/Destructuring_assignment","destructuring assignment","","true")}}.</p>
+
+<pre class="brush: js notranslate">for(let value of ["a", "b", "c"]){
+ console.log(value)
+}
+// "a"
+// "b"
+// "c"
+
+[..."abc"] // ["a", "b", "c"]
+
+function* gen(){
+ yield* ["a", "b", "c"]
+}
+
+gen().next() // { value:"a", done:false }
+
+[a, b, c] = new Set(["a", "b", "c"])
+a // "a"
+
+</pre>
+
+<h2 id="Generators">Generators</h2>
+
+<p>Enquanto os iteradores são ferramentas muito úteis, sua criação requer um cuidado devido a necessidade de manter explicito seu estado interno. <strong>{{jsxref("Global_Objects/Generator","Generators","","true")}}</strong> provê uma alternativa poderosa: eles te permitem definir um algorítimo iterativo escrevendo uma função simples que pode manter seu estado próprio.</p>
+
+<p>Generator é um tipo especial de função que trabalha como uma factory para iteradores. A função vira um generator se ela contém uma ou mais expressões {{jsxref("Operators/yield","yield")}} e se ela usa a sintaxe {{jsxref("Statements/function*","function*")}}.</p>
+
+<pre class="brush: js notranslate">function* idMaker(){
+ var index = 0;
+ while(true)
+ yield index++;
+}
+
+var gen = idMaker();
+
+console.log(gen.next().value); // 0
+console.log(gen.next().value); // 1
+console.log(gen.next().value); // 2
+// ...</pre>
+
+<h2 id="Generators_avançados">Generators avançados</h2>
+
+<p>Generators computam seus valores "yielded" por demanda, que os permitem representar sequencias de forma eficiente que costumam ser trabalhosas ao serem computadas, ou até sequencias infinitas como demonstradas acima.</p>
+
+<p>O método {{jsxref("Global_Objects/Generator/next","next()")}} também aceita um valor que pode ser usado para modificar o estado interno de um generator. O valor passado pro <code>next()</code> será tratado como o resultado da última expressão yield que pausou o generator.</p>
+
+<p>Aqui um gerador de sequencia fibonacci usando <code>next(x)</code> pra restartar a sequencia:</p>
+
+<pre class="brush: js notranslate">function* fibonacci(){
+ var fn1 = 1;
+ var fn2 = 1;
+ while (true){
+ var current = fn2;
+ fn2 = fn1;
+ fn1 = fn1 + current;
+ var reset = yield current;
+ if (reset){
+ fn1 = 1;
+ fn2 = 1;
+ }
+ }
+}
+
+var sequence = fibonacci();
+console.log(sequence.next().value); // 1
+console.log(sequence.next().value); // 1
+console.log(sequence.next().value); // 2
+console.log(sequence.next().value); // 3
+console.log(sequence.next().value); // 5
+console.log(sequence.next().value); // 8
+console.log(sequence.next().value); // 13
+console.log(sequence.next(true).value); // 1
+console.log(sequence.next().value); // 1
+console.log(sequence.next().value); // 2
+console.log(sequence.next().value); // 3</pre>
+
+<div class="note"><strong>Nota:</strong> Como um ponto de interesse, chamando <code>next(undefined)</code> é o mesmo que chamar <code>next()</code>. Entretanto, estartar um novo generator com qualquer valor que não seja undefined na chamada next() terá <code>TypeError</code> exception.</div>
+
+<p>Você pode forçar um generator a lançar uma exceção chamando o seu método {{jsxref("Global_Objects/Generator/throw","throw()")}}  e passando o valor da exceção que ele deve lançar. Essa exceção será lançada do contexto suspenso atual do generator, como se o <code>yield</code> atualmente suspenso fosse um <code>throw</code>.</p>
+
+<p>Se um yield não for encontrado durante o processo de lançamento de um thrown exception, então o exception será propagado através da chamada do <code>throw()</code>, e pra subsequente chamada do <code>next()</code> que terá a propriedade done resultando em <code>true</code>.</p>
+
+<p>Generators tem o método {{jsxref("Global_Objects/Generator/return","return(value)")}} que retorna o valor pego e finaliza o generator.</p>
+
+<p>{{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Meta_programming")}}</p>