O que é “function *” em JavaScript?

Nesta página eu encontrei um novo tipo de function JavaScript:

// NOTE: "function*" is not supported yet in Firefox. // Remove the asterisk in order for this code to work in Firefox 13 function* fibonacci() { // !!! this is the interesting line !!! let [prev, curr] = [0, 1]; for (;;) { [prev, curr] = [curr, prev + curr]; yield curr; } } 

Eu já sei o que yield , let e [?,?]=[?,?] Fazer , mas não tenho idéia do que a function* deve ser. O que é isso?

PS não se incomoda tentando Google, é impossível procurar por expressões com asteriscos ( eles são usados ​​como espaços reservados ).

   

É uma function de gerador .

Geradores são funções que podem ser encerradas e depois reinseridas. Seu contexto (ligações variables) será salvo entre as reentrâncias.

Chamar uma function de gerador não executa seu corpo imediatamente; um object iterador para a function é retornado em vez disso. Quando o método next() do iterador é chamado, o corpo da function geradora é executado até a primeira expressão yield , que especifica o valor a ser retornado pelo iterador ou, com yield* , delega a outra function geradora.


Nota Histórica:

É uma syntax proposta para o EcmaScript.next .

Dave Herman, da Mozilla, fez uma palestra sobre EcmaScript.next . Às 30:15 ele fala sobre geradores.

Anteriormente, ele explica como a Mozilla está implementando experimentalmente mudanças de linguagem propostas para ajudar a orientar o comitê. Dave trabalha de perto com Brendan Eich, CTO da Mozilla (eu acho), e o designer original do JavaScript.

Você pode encontrar mais detalhes no wiki do grupo de trabalho EcmaScript: http://wiki.ecmascript.org/doku.php?id=harmony:generators

O grupo de trabalho (TC-39) tem um consenso geral de que o EcmaScript.next deve ter algum tipo de proposta de iterador de gerador, mas isso não é definitivo.

Você não deve confiar em que isso apareça sem alterações na próxima versão do idioma e, mesmo que isso não mude, provavelmente ele não será exibido amplamente em outros navegadores por um tempo.

Visão geral

Coroutines de primeira class, representadas como objects que encapsulam contextos de execução suspensos (por exemplo, ativações de function). Arte prévia: Python, Icon, Lua, Scheme, Smalltalk.

Exemplos

A sequência “infinita” dos números de Fibonacci (não obstante o comportamento em torno de 2 53 ):

 function* fibonacci() { let [prev, curr] = [0, 1]; for (;;) { [prev, curr] = [curr, prev + curr]; yield curr; } } 

Geradores podem ser iterados em loops:

 for (n of fibonacci()) { // truncate the sequence at 1000 if (n > 1000) break; print(n); } 

Geradores são iteradores:

 let seq = fibonacci(); print(seq.next()); // 1 print(seq.next()); // 2 print(seq.next()); // 3 print(seq.next()); // 5 print(seq.next()); // 8 

É uma function geradora – e assim foi dito na página que você cita, no comentário que você substituiu por “essa é a linha interessante” …

Basicamente, é uma maneira de especificar seqüências programaticamente para que elas possam ser passadas e elementos acessados ​​por índice sem ter que calcular a seqüência inteira (possivelmente infinita em tamanho) antecipadamente.

O tipo da function* parece funcionar como uma function geradora para processos que podem ser iterados. C # tem um recurso como este usando “retorno de rendimento”, ver 1 e ver 2

Essencialmente, isso retorna cada valor um por um para qualquer coisa que esteja iterando essa function, e é por isso que seu caso de uso a mostra em um loop de estilo foreach.