diff options
author | Florian Merz <me@fiji-flo.de> | 2021-02-11 14:49:58 +0100 |
---|---|---|
committer | Florian Merz <me@fiji-flo.de> | 2021-02-11 14:49:58 +0100 |
commit | 68fc8e96a9629e73469ed457abd955e548ec670c (patch) | |
tree | 8529ab9fe63d011f23c7f22ab5a4a1c5563fcaa4 /files/pt-br/web/javascript/guide/iterators_and_generators | |
parent | 8260a606c143e6b55a467edf017a56bdcd6cba7e (diff) | |
download | translated-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.html | 161 |
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) => { + +let nextIndex = 0; + +return { + next : () => { + return nextIndex < 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> |