2012-02-18 10 views
26

In Chrome, quando digito console.log in quella sottostante:Javascript: parametri "infiniti" per la funzione?

console.log("A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter"); 

... la stampa in modo corretto, senza errori o avvisi. Ho aggiunto altri parametri, ma lo stampa ancora correttamente.

console.log("A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter"); 

Come posso avere una funzione "infinita" come quella?

risposta

46

funzioni possono accedere a un oggetto array-come detto arguments che contiene tutti gli argomenti che hanno ricevuto

function print_my_arguments(/**/){ 
    var args = arguments; 
    for(var i=0; i<args.length; i++){ 
     console.log(args[i]); 
    } 
}; 

e si può fare la conversione opposta (chiamare una funzione data una lista di argomenti) con il metodo apply :

// These are equivalent: 
print_my_arguments(1,2,3); 
print_my_arguments.apply(null, [1,2,3]); 

// The first parameter to `apply` is the `this`. 
// It is used when the function is a method. 
foo.bar(1,2,3); 
var f = foo.bar; f.apply(foo, [1,2,3]); 

Alcuni punti importanti da notare:

  1. arguments non è un array effettivo e non ha nessuno dei soliti metodi di array (slice, join, ecc.). È possibile convertirlo in un array con la seguente riga:

    var args = Array.prototype.slice.call(arguments); 
    
  2. Slice è anche utile se si desidera l'array contenga solo gli argomenti non di nome che sono stati ricevuti:

    function foo(first_arg, second_arg /**/){ 
        var variadic_args = Array.prototype.slice.call(arguments, 2); 
    } 
    
  3. Non

    ogni browser può gestire un numero arbitrariamente elevato di parametri di funzione. L'ultima volta che l'ho provato, in Chrome e IE c'era uno stackoverflow dopo circa 200.000 argomenti. Se la funzione può ricevere un numero arbitrariamente elevato di argomenti, prendere in considerazione la possibilità di impacchettare tutti questi argomenti in una matrice regolare.

  4. Quei /**/ commenti che compaiono negli elenchi di argomenti per i miei esempi non sono obbligatori. Sono solo una codifica di una convenzione che uso per marcare le mie funzioni variadiche e differenziarle dalle normali funzioni.

    // A quick glance would suggest that this function receives no 
    // parameters but actually it is a variadic function that gets 
    // its parameters via the `arguments` object. 
    function foo(){ 
        console.log(arguments.length); 
    } 
    
+0

grande risposta, uno per gli avvertimenti, non ho letto loro e corse il primo. –

0

È possibile utilizzare la matrice argomenti: jsfiddle.net/kUnJ2/

+0

Questa è una ripetizione della risposta precedente. In futuro, è utile se puoi fornire una risposta alternativa o aggiungere valore alle risposte esistenti –

Problemi correlati