Passando un array come parametro di funzione in JavaScript


291

Vorrei chiamare una funzione usando un array come parametri:

const x = ['p0', 'p1', 'p2'];
call_me(x[0], x[1], x[2]); // I don't like it

function call_me (param0, param1, param2 ) {
  // ...
}

Esiste un modo migliore per trasmettere il contenuto di xin call_me()?

Risposte:


422
const args = ['p0', 'p1', 'p2'];
call_me.apply(this, args);

Consulta i documenti MDN per Function.prototype.apply().


Se l'ambiente supporta ECMAScript 6, è possibile utilizzare invece un argomento spread :

call_me(...args);

9
Come nota a margine, se qualcuno vuole invece passare una matrice associativa (denominata chiavi), usa un oggetto. Venendo da PHP (e sempre portato a questa discussione da Google), mi ci è voluto un po 'di tempo per capire. Quindi è possibile passare l'intero oggetto come parametro. w3schools.com/js/js_objects.asp
timhc22

Grazie per aver sottolineato l'argomento 'diffusione'! Non lo sapevo.
Thomas Un

@timhc - il commento della tua nota a margine è intrigante, ma non riesco ad analizzarlo (sono un noob javascript che lavora attraverso un paio di tutorial). In JS, un array associativo è un oggetto secondo diversi tutorial.
NateT,

@ timhc22 e quando si utilizza l'oggetto json per passare come parametro a una funzione, non dimenticare la distruzione dei parametri per una migliore leggibilità
Muhammad Omer Aslam,

113

Perché non si passa l'intero array e lo si elabora secondo necessità all'interno della funzione?

var x = [ 'p0', 'p1', 'p2' ]; 
call_me(x);

function call_me(params) {
  for (i=0; i<params.length; i++) {
    alert(params[i])
  }
}

37
È perché non riesco a modificare call_me (). È definito in qualche altra libreria e non è possibile scherzare con l'API.
Robert,

62
+1 perché anche se non risponde alla domanda originale, è probabilmente quello che cercavano le persone con oltre 100.000 utenti che hanno visualizzato questa pagina.
Ishikawa,

Qualcuno può spiegare cosa sta facendo la linea "call_me (x)"? Sembra che sia un nome di funzione senza la parola chiave funzione? Che cosa sta facendo esattamente?
Nuotato il

1
@swam È una chiamata alla call_mefunzione. Manca solo un punto e virgola alla fine.
SantiBailors,

@swam sta mettendo in atto la funzione call_me (params) dichiarata.
Julio Rodriguez

43

Supponendo che call_me sia una funzione globale, quindi non ti aspetti che sia impostato.

var x = ['p0', 'p1', 'p2'];
call_me.apply(null, x);


7

Come aveva risposto @KaptajnKold

var x = [ 'p0', 'p1', 'p2' ];
call_me.apply(this, x);

E non è nemmeno necessario definire tutti i parametri per la funzione call_me. Puoi solo usarearguments

function call_me () {
    // arguments is a array consisting of params.
    // arguments[0] == 'p0',
    // arguments[1] == 'p1',
    // arguments[2] == 'p2'
}

4
Questa è una brutta pratica ... non sarai in grado di vedere di cosa ha bisogno la funzione e ogni parametro è facoltativo se guardi la funzione.
Robin,

3

Nota questo

function FollowMouse() {
    for(var i=0; i< arguments.length; i++) {
        arguments[i].style.top = event.clientY+"px";
        arguments[i].style.left = event.clientX+"px";
    }

};

// ---------------------------

pagina HTML

<body onmousemove="FollowMouse(d1,d2,d3)">

<p><div id="d1" style="position: absolute;">Follow1</div></p>
<div id="d2" style="position: absolute;"><p>Follow2</p></div>
<div id="d3" style="position: absolute;"><p>Follow3</p></div>


</body>

può chiamare la funzione con qualsiasi argomento

<body onmousemove="FollowMouse(d1,d2)">

o

<body onmousemove="FollowMouse(d1)">

Questo fa chiaramente parte della risposta. "argomenti" è sicuramente necessario per ripristinare l'array dopo la chiamata. Grazie!
FlorianB,

2

Gli argomenti delle funzioni possono anche essere matrici:

function foo([a,b,c], d){
  console.log(a,b,c,d);
}

foo([1,2,3], 4)

ovviamente si può anche usare spread :

function foo(a, b, c, d){
  console.log(a, b, c, d);
}

foo(...[1, 2, 3], 4)


2

Durante l'utilizzo dell'operatore spread, dobbiamo notare che deve essere l'ultimo o l'unico parametro passato. Altrimenti fallirà.

function callMe(...arr){ //valid arguments
    alert(arr);
}

function callMe(name, ...arr){ //valid arguments
    alert(arr);
}

function callMe(...arr, name){ //invalid arguments
    alert(arr);
}

Se è necessario passare un array come argomento iniziale, è possibile:

function callMe(arr, name){
    let newArr = [...arr];
    alert(newArr);
}

1

puoi utilizzare l'operatore di diffusione in una forma più semplice

[].concat(...array)

nel caso di funzioni che restituiscono array ma che devono passare come argomenti

Esempio:

function expectArguments(...args){
  return [].concat(...args);
}

JSON.stringify(expectArguments(1,2,3)) === JSON.stringify(expectArguments([1,2,3]))

0

La risposta è già stata data, ma voglio solo dare il mio pezzo di torta. Quello che vuoi ottenere è chiamato method borrowingnel contesto di JS, che quando prendiamo un metodo da un oggetto e lo chiamiamo nel contesto di un altro oggetto. È abbastanza comune prendere metodi array e applicarli agli argomenti. Lasciate che vi faccia un esempio.

Quindi abbiamo la funzione di hashing "super" che accetta due numeri come argomento e restituisce una stringa hash "super sicura":

function hash() {
  return arguments[0]+','+arguments[1];
}

hash(1,2); // "1,2" whoaa

Fin qui tutto bene, ma abbiamo pochi problemi con l'approccio sopra, è limitato, funziona solo con due numeri, che non è dinamico, facciamolo funzionare con qualsiasi numero e inoltre non devi passare un array (puoi se insisti ancora). Ok, basta parlare, litighiamo!

La soluzione naturale sarebbe quella di utilizzare il arr.joinmetodo:

function hash() {
  return arguments.join();
}

hash(1,2,4,..); //  Error: arguments.join is not a function

Oddio. Sfortunatamente, non funzionerà. Perché stiamo chiamando hash (argomenti) e argomenti object è sia iterabile che simile a array, ma non un array reale. Che ne dici dell'approccio sotto?

function hash() {
  return [].join.call(arguments);
}

hash(1,2,3,4); // "1,2,3,4" whoaa

Il trucco si chiama method borrowing.

Prendiamo in prestito un joinmetodo da un array normale [].join.e lo utilizziamo [].join.callper eseguirlo nel contesto di arguments.

Perché funziona

Questo perché l'algoritmo interno del metodo nativo arr.join(glue) è molto semplice.

Tratto dalla specifica quasi "così com'è":

Let glue be the first argument or, if no arguments, then a comma ",".
Let result be an empty string.
Append this[0] to result.
Append glue and this[1].
Append glue and this[2].
Do so until this.length items are glued.
Return result.

Quindi, tecnicamente prende questo e unisce questo [0], questo [1] ... ecc. Insieme. È intenzionalmente scritto in un modo che consente qualsiasi array simile a questo (non una coincidenza, molti metodi seguono questa pratica). Ecco perché funziona anche conthis=arguments.

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.