2013-08-12 26 views
13

A volte vedo JavaScript scritto con un argomento purché abbia già un valore impostato o sia un oggetto con metodi. Prendete questo esempio jQuery per esempio:Passare argomenti in funzioni anonime in JavaScript

$(".selector").children().each(function(i) { 
    console.log(i); 
}); 

Quando si accede i, si dovrebbe ottenere il valore di qualsiasi i è in quella iterazione se si considerano i selettori bambini nel metodo di jQuery each.

Prendete questo Node.JS esempio:

http.createServer(function(request, response) { 
    response.writeHead(200, {"Content-Type": "text/plain"}); 
    response.write("Hello World"); 
    response.end(); 
}).listen(8888); 

si può vedere qui che request e response vengono passati e contengono i propri metodi che possono essere agito su.

Per me, sembra che si passasse una funzione alla funzione createServer con due argomenti con metodi già associati.

La mia domanda è un multipart uno:

  1. Da dove vengono questi argomenti vengono?
  2. Se queste sono solo funzioni anon, in che modo ricevono argomenti che possono essere interpretati come altre funzioni?
  3. Come posso creare funzioni che possono prendere i miei argomenti in questo modo ??
  4. Questo usa la potenza delle chiusure ??

risposta

13

Per me, sembra che si passasse una funzione alla funzione createServer con due argomenti con metodi già associati.

No. Stavano passando una funzione a createServer che accetta due argomenti. Queste funzioni saranno successivamente chiamati con qualunque sia l'argomento del chiamante mette ad esempio:.

function caller(otherFunction) { 
    otherFunction(2); 
} 
caller(function(x) { 
    console.log(x); 
}); 

stamperà 2.

più avanzati, se questo non è ciò che si desidera è possibile utilizzare il metodo bind appartiene a tutte le funzioni, che creeranno una nuova funzione con argomenti specificati già associati. per esempio.:

caller(function(x) { 
    console.log(x); 
}.bind(null, 3); 
}); 

stamperà 3, e l'argomento 2 passato alla funzione anonima diventerà un argomento inutilizzato e senza nome.

Ad ogni modo, questo è un esempio denso; si prega di controllare la documentazione collegata per bind per capire come funziona meglio l'associazione.

+0

Ma come fa 'request' e' risposta' nel mio esempio di nodo hanno già metodi ?? Questo non ha senso per me. – Sethen

+0

@SethenMaleno: cosa intendi con "già"? I parametri non hanno valori finché non viene chiamata la funzione. – Bergi

+1

@SethenMaleno 'request' e' response' sono solo parametri per il metodo 'createServer'. Quando viene effettivamente chiamato quel metodo, verranno passati due oggetti, che rappresentano una richiesta e una risposta che è possibile manipolare. La dichiarazione dei parametri imposta semplicemente ciò che la funzione si aspetta; la magia accade quando la funzione è chiamata – Ian

0

Sì, si passano le funzioni come argomenti. Le funzioni che passerai avranno ovviamente i loro argomenti.

E, questi argomenti possono essere qualsiasi cosa, compresi gli oggetti che possono avere i propri metodi, ecc

http.createServer accetterà una funzione ed saprà argomenti come maggio che la funzione ha. Un modo per farlo è verificare la proprietà arguments della funzione passata. Oppure lo sviluppatore di api potrebbe aver usato gli elementi reali.

L'autore di questa funzione saprà cosa è previsto come argomento e lo documenterà nello api documentation.

3

Diamo uno sguardo al $.each per l'esempio:

each: function (obj, callback, args) { 
    var value, 
    i = 0, 
     length = obj.length, 
     isArray = isArraylike(obj); 

    if (args) { 
     if (isArray) { 
      for (; i < length; i++) { 
       value = callback.apply(obj[i], args); 

       if (value === false) { 
        break; 
       } 
      } 
     } else { 
      for (i in obj) { 
       value = callback.apply(obj[i], args); 

       if (value === false) { 
        break; 
       } 
      } 
     } 

     // A special, fast, case for the most common use of each 
    } else { 
     if (isArray) { 
      for (; i < length; i++) { 
       value = callback.call(obj[i], i, obj[i]); 

       if (value === false) { 
        break; 
       } 
      } 
     } else { 
      for (i in obj) { 
       value = callback.call(obj[i], i, obj[i]); 

       if (value === false) { 
        break; 
       } 
      } 
     } 
    } 

    return obj; 
} 

Questo viene chiamato da

$(".selector").children().each(function(i) { 
    console.log(i); 
}); 

come:

return $.each.call(this, callback /* this is your function */, args /* which is an additional thing people rarely use*/) 

Questa è la linea (nel primo blocco) vuoi dare un'occhiata a

callback.call(obj[i], i, obj[i]); 

Sta chiamando il callback e passando l'oggetto come contesto: ecco perché è possibile utilizzare this nel ciclo. Quindi l'iterazione i e quindi lo stesso oggetto del contesto vengono entrambi inviati come argomenti al callback. È un po 'come la magia; finché non guardi il codice sorgente.

0

Se avete guardato il codice per createServer, sarebbe simile a questa:

function createServer (handleRequestAndResponseFunction) { 
    handleRequestAndResponseFunction(actualRequest, actualReponse); 
} 

ok, no, no, ma è un semplice esempio. createServer accetta uno function che accetta due argomenti.

In termini più realistici, quando si passa a quella funzione di due argomenti, esegue qualsiasi elaborazione middleware e gli elementi necessari, quindi chiama tale funzione, passando le proprie variabili di richiesta e risposta.

0

Ecco un esempio di passaggio di parametri in funzione anonima

var a = 'hello'; 

    // Crockford 
    (function(a){alert(a)}(a)); 

    // Others 
    (function(a){alert(a)})(a); 

Esso utilizza la chiusura, dal momento che è una funzione anonima (in realtà tutto dipende da come l'avete scritto)

Problemi correlati