function*
La dichiarazione function*
(la parola chiave function
seguita da un asterisco) definisce una funzione generatrice, la quale restituisce un oggetto di tipo Generator
.
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
È anche possibile definire una funzione generatrice usando il costrutto GeneratorFunction
e una espressione function*
(en-US).
Sintassi
function* nome([param[, param[, ... param]]]) { istruzioni }
nome
- Il nome della funzione.
param
- Gli argomenti passati alla funzione. Una funzione può avere fino a 255 argomenti.
istruzioni
- Le istruzioni che compongono il corpo della funzione.
Descrizione
I generatori sono funzioni dalle quali è possibile uscire e poi rientrarvi in un secondo momento. Il loro contesto (binding delle variabili) verrà salvato all'uscita per quando vi entrerà successivamente.
La chiamata ad un generatore non viene eseguita immediatamente; la funzione ritornerà invece un oggetto iterator. Quando il metodo next()
dell'iteratore viene chiamato, il corpo del generatore viene eseguito fino alla prima espressione yield
, la quale specifica quale espressione ritornare dall'iteratore oppure, con l'espressione yield*
(en-US), delegare questo valore ad un'altra funzione generatrice. Il metodo next()
restituisce un oggetto con proprietà value
contenente il valore da restituito all'iteratore ed una proprietà done
che contiene un valore di tipo boolean per indicare se il generatore ha restituito l'ultimo valore. Chiamando il metodo next()
con un argomento farà riprendere l'esecuzione della funzione generatrice, sostituendo l'istruzione yield
in cui l'esecuzione era stata fermata con l'argomento della funzione next()
.
Esempi
Esempio semplice
function* idMaker(){
var index = 0;
while(index < 3)
yield index++;
}
var gen = idMaker();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // undefined
// ...
Esempio con yield*
function* anotherGenerator(i) {
yield i + 1;
yield i + 2;
yield i + 3;
}
function* generator(i){
yield i;
yield* anotherGenerator(i);
yield i + 10;
}
var gen = generator(10);
console.log(gen.next().value); // 10
console.log(gen.next().value); // 11
console.log(gen.next().value); // 12
console.log(gen.next().value); // 13
console.log(gen.next().value); // 20
Passare argomenti ai Generatori
function* logGenerator() {
console.log(yield);
console.log(yield);
console.log(yield);
}
var gen = logGenerator();
// the first call of next executes from the start of the function
// until the first yield statement
gen.next();
gen.next('pretzel'); // pretzel
gen.next('california'); // california
gen.next('mayonnaise'); // mayonnaise
I generatori non sono costruttori
function* f() {}
var obj = new f; // solleva "TypeError: f is not a constructor"
Specifiche
Specifica | Stato | Commenti |
---|---|---|
ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'function*' in that specification. |
Standard | Definizione iniziale |
ECMAScript 2016 (ECMA-262) The definition of 'function*' in that specification. |
Standard | I generatori non devono avere essere usati come costruttori e deveo lanciare un eccezione quando vengono usati con la parola chiave new . |
ECMAScript (ECMA-262) The definition of 'function*' in that specification. |
Living Standard |
Compatibilità per i browser
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Edge | Opera | Safari (WebKit) |
---|---|---|---|---|---|---|
Supporto base | 39.0 | 26.0 (26.0) | No support | 13 | 26 | No support |
yield* |
(Yes) | 27.0 (27.0) | No support | 13 | 26 | No support |
IteratorResult invece delle eccezioni |
(Yes) | 29.0 (29.0) | No support | 13 | (Yes) | No support |
Non istanziabile con new {ES2016) |
(Yes) | 43.0 (43.0) | ? | ? | ? | ? |
Feature | Android | Android Webview | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile | Chrome for Android |
---|---|---|---|---|---|---|---|
Supporto base | No support | (Yes) | 26.0 (26.0) | No support | No support | No support | 39.0 |
yield* |
No support | (Yes) | 27.0 (27.0) | No support | No support | No support | (Yes) |
IteratorResult invece delle eccezioni |
No support | ? | 29.0 (29.0) | No support | No support | No support | (Yes) |
Non istanziabile con new (ES2016) |
? | ? | 43.0 (43.0) | ? | ? | ? | ? |
Note specifiche per Firefox
Generatori e iteratori in Firefox nelle versioni precedenti alla 26
Versioni di FIrefox precedenti implementano una versione più vecchia della proposta di standard per i generatori. Tra le varie differenze, in queste versioni i generatori erano definiti usando la parola chiave function
(senza asterisco) per le funzioni semplici. Per maggiori informazioni fare riferimento a funzioni generatrici (legacy)
.
IteratorResult
al posto delle eccezioni
A partire da Gecko 29 (Firefox 29 / Thunderbird 29 / SeaMonkey 2.26), la funzione generatrice completata non solleva più eccezioni TypeError
"generator has already finished". Restituisce invece oggetti di tipo IteratorResult
come il seguente { value: undefined, done: true }
(bug 958951).
Vedi anche
Espressione function*
(en-US)- Oggetto
GeneratorFunction
- The Iterator protocol
yield
yield*
(en-US)- Oggetto
Function
dichiarazione di funzioni
(en-US)espressione function
(en-US)Funzioni e scope di funzioni
- Altre risorse sul web:
- Regenerator un compilatore di generatori da ES5 a ES5 [Inglese]
- Forbes Lindesay: Promises and Generators: control flow utopia -- JSConf EU 2013 [Inglese]
- Hemanth.HM: The New gen of *gen(){} [Inglese]
- Task.js [Inglese]