Che cos'è la "funzione *" in JavaScript?


243

In questa pagina ho trovato un nuovo tipo di funzione 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;
    }
}

So già cosa yield, lete [?,?]=[?,?]faccio , ma non ho idea di cosa function*significhi essere. Che cos'è?

PS non si preoccupa di provare Google, è impossibile cercare espressioni con asterischi ( sono usati come segnaposto ).


4
Il commento nell'esempio è piuttosto vecchio ora, la function*sintassi è supportata in Firefox dal v26: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… *. Le versioni precedenti utilizzavano una sintassi diversa.
Nickolay,

39
Per quanto riguarda Google, basta cercare "star funzione" o "asterisco funzione". È così che ho trovato questa domanda;).
trysis,

2
Sembra che sia *stato rimosso dal link di @Nickolay. Ecco un link direttamente function*a MDN . Abbastanza sicuro, supporto "base" dalla v26 .
ruffin,

Un altro collegamento MDN (che, tra l'altro, ho trovato nella pagina MDN collegato tramite OP) : developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
BlueRaja - Danny Pflughoeft

Risposte:


199

È una funzione del generatore .

I generatori sono funzioni che possono essere abbandonate e successivamente reinserite. Il loro contesto (collegamenti variabili) verrà salvato tra i rientri.

La chiamata di una funzione generatore non esegue immediatamente il suo corpo; viene invece restituito un oggetto iteratore per la funzione. Quando next()viene chiamato il metodo dell'iteratore , il corpo della funzione generatore viene eseguito fino alla prima yieldespressione, che specifica il valore da restituire dall'iteratore o, con yield*, delega a un'altra funzione generatore.


Nota storica:

È una sintassi proposta per EcmaScript.next.

Dave Herman di Mozilla ha tenuto un discorso su EcmaScript.next . Alle 30:15 parla di generatori.

In precedenza, spiega come Mozilla sta implementando sperimentalmente le modifiche linguistiche proposte per aiutare a guidare il comitato. Dave lavora a stretto contatto con Brendan Eich, CTO di Mozilla (credo) e il designer JavaScript originale.

Puoi trovare maggiori dettagli sul wiki del gruppo di lavoro EcmaScript: http://wiki.ecmascript.org/doku.php?id=harmony:generators

Il gruppo di lavoro (TC-39) ha un accordo generale sul fatto che EcmaScript.next dovrebbe avere una sorta di proposta di iteratore del generatore, ma questo non è definitivo.

Non dovresti fare affidamento sul fatto che questo venga mostrato senza modifiche nella prossima versione della lingua e anche se non cambia, probabilmente non verrà visualizzato ampiamente in altri browser per un po '.

Panoramica

Coroutine di prima classe, rappresentati come oggetti che incapsulano contesti di esecuzione sospesi (ovvero attivazioni di funzioni). Arte nota: Python, Icon, Lua, Scheme, Smalltalk.

Esempi

La sequenza "infinita" di numeri di Fibonacci (nonostante il comportamento attorno a 2 53 ):

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

I generatori possono essere ripetuti in loop:

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

I generatori sono iteratori:

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

7
Follow up: cosa fa un ciclo for senza parametri ( for(;;))? Perché usarlo in questo contesto?
Fergie,

13
@Fergie, for(;;)è lo stesso di while (true). È usato in questo contesto poiché la sequenza di Fibonacci è una sequenza illimitata.
Mike Samuel,

5
Arte nota: resa in C #?
Dave Van den Eynde,

3
@DaveVandenEynde, tecnica nota: resa in Python. Arte nota anteriore: CLU e Icon.
Mike Samuel,

52

È una funzione del generatore - e lo diceva nella pagina che citi, nel commento che hai sostituito con "questa è la linea interessante" ...

Fondamentalmente è un modo per specificare le sequenze a livello di codice in modo che possano essere passate in giro e gli elementi accessibili tramite indice senza dover prima calcolare l'intera sequenza (possibilmente di dimensioni infinite).


10
"L'accesso per indice senza dover calcolare l'intera sequenza" è probabilmente la spiegazione più utile sui generatori che ho trovato finora. L'ho visto in un'app, rispetto a prima semplicemente capendolo teoricamente.
Siamo il

11

Il function*tipo sembra agire come una funzione del generatore per i processi che possono essere iterati. C # ha una funzione come questa usando "rendimento", vedi 1 e vedi 2

Essenzialmente questo restituisce ogni valore uno per uno a qualunque cosa stia ripetendo questa funzione, motivo per cui il loro caso d'uso lo mostra in un ciclo di stile foreach.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.