2011-09-03 5 views
64

ho preso un pezzo di codice JavaScript che io proprio non capisco:JavaScript funzione nidificata

function dmy(d) { 
    function pad2(n) { 
     return (n < 10) ? '0' + n : n; 
    } 

    return pad2(d.getUTCDate()) + '/' + 
     pad2(d.getUTCMonth() + 1) + '/' + 
     d.getUTCFullYear(); 
} 

function outerFunc(base) { 
    var punc = "!"; 

    //inner function 
    function returnString(ext) { 
     return base + ext + punc; 
    } 

    return returnString; 
} 

Come può una funzione di essere definiti all'interno di un'altra funzione? Possiamo chiamare pad2() dall'esterno della mia funzione my()?

Per favore, accendilo. Grazie

+8

funzioni possono essere creati all'interno di funzioni. Questo è perfettamente valido. – 0x499602D2

risposta

109

Le funzioni sono un altro tipo di variabile in JavaScript (con alcune sfumature ovviamente). La creazione di una funzione all'interno di un'altra funzione modifica l'ambito della funzione nello stesso modo in cui cambierebbe l'ambito di una variabile. Questo è particolarmente importante per l'uso con chiusure per ridurre l'inquinamento totale dello spazio dei nomi globale.

Le funzioni definite all'interno di un'altra funzione non sarà accessibile all'esterno della funzione a meno che non sono stati attaccati ad un oggetto che è accessibile dall'esterno della funzione:

function foo(doBar) 
{ 
    function bar() 
    { 
    console.log('bar'); 
    } 

    function baz() 
    { 
    console.log('baz'); 
    } 

    window.baz = baz; 
    if (doBar) bar(); 
} 

In questo esempio, la funzione baz sarà disponibile per l'uso dopo l'esecuzione della funzione foo, poiché è stata sostituita con window.baz. La funzione barra non sarà disponibile in alcun contesto diverso dagli ambiti contenuti nella funzione foo.

come un esempio diverso:

function Fizz(qux) 
{ 
    this.buzz = function(){ 
    console.log(qux); 
    }; 
} 

La funzione Fizz è progettato come un costruttore in modo che, quando eseguito, si assegna una funzione buzz all'oggetto appena creato.

+0

Che cos'è window.baz = baz? Perché questa linea m? Ke baz è disponibile? –

+0

@ZiyangZhang, il paragrafo dopo che il blocco di codice ha la spiegazione, c'era una parte particolare che non è chiara? – zzzzBov

+0

Questo è inefficiente sia in velocità che in memoria .. vedi la mia risposta qui sotto – kofifus

12
function x() {} 

è equivalente (o molto simile) per

var x = function() {} 

se non mi sbaglio.

Quindi non c'è niente di divertente in corso.

+5

La prima sintassi verrà spostata all'inizio del documento. quindi è possibile chiamare la funzione 'x' prima che il funtion sia inizializzato. – Tom

+5

La prima sintassi ti consentirà di ottenere tracce dello stack ancora più piacevoli con funzioni denominate, la seconda ti darà un mal di testa – TheZ

7

L'istanza delle funzioni è consentita all'interno e all'esterno delle funzioni. All'interno di queste funzioni, proprio come le variabili, le funzioni nidificate sono locali e quindi non possono essere ottenute dall'ambito esterno.

function foo() { 
    function bar() { 
     return 1; 
    } 
    return bar(); 
} 

foo manipola bar in sé. bar non può essere toccato dall'ambito esterno a meno che non sia definito nell'ambito esterno.

Quindi questo non funzionerà:

function foo() { 
    function bar() { 
     return 1; 
    } 
} 

bar(); // throws error: bar is not defined 
3

è perfettamente normale in Javascript (e molte lingue) per avere funzioni all'interno funzioni.

Prendetevi del tempo per imparare la lingua, non usarla sulla base del fatto che è simile a ciò che già sapete. Suggerisco di guardare la serie di presentazioni YUI di Douglas Crockford su Javascript, con particolare attenzione su Act III: Function the Ultimate (collegamento al download di video, diapositive e trascrizione)

4

Quando si dichiara una funzione all'interno di una funzione, le funzioni interne sono disponibili solo nell'ambito in cui sono dichiarate, oppure nel proprio caso lo pad2 può essere chiamato solo nell'ambito dmy.

Tutte le variabili esistenti in dmy sono visibili nella pad2, ma non accade il contrario: D

26

Si chiama chiusura.

Fondamentalmente, la funzione definita all'interno di un'altra funzione è accessibile solo all'interno di questa funzione. Ma può essere passato come risultato e quindi questo risultato può essere chiamato.

È una funzionalità molto potente. Si può vedere di più spiegazione qui:

javascript_closures_for_dummies.html mirror on Archive.org