Passer un tableau en tant que paramètre de fonction en JavaScript


291

Je voudrais appeler une fonction en utilisant un tableau comme paramètres:

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

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

Existe-t-il une meilleure façon de transmettre le contenu de xen call_me()?

Réponses:


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

Voir les documents MDN pour Function.prototype.apply().


Si l'environnement prend en charge ECMAScript 6, vous pouvez utiliser un argument de propagation à la place:

call_me(...args);

9
En remarque, si quelqu'un veut passer un tableau associatif (clés nommées) à la place, utilisez un objet. Venant de PHP (et toujours conduit à ce fil par google), cela m'a pris du temps à comprendre. Vous pouvez alors passer tout l'objet en tant que paramètre. w3schools.com/js/js_objects.asp
timhc22

Merci d'avoir souligné l'argument «propagation»! Je n'en savais rien.
Thomas An

@timhc - votre commentaire de note secondaire est intrigant, mais je ne peux pas l'analyser (je suis un noob javascript travaillant à travers quelques tutoriels). Dans JS, un tableau associatif est un objet selon plusieurs tutoriels.
NateT

@ timhc22, et lorsque vous utilisez l'objet json pour passer en paramètre à une fonction, n'oubliez pas la destruction des paramètres pour une meilleure lisibilité
Muhammad Omer Aslam

113

Pourquoi ne transmettez-vous pas l'ensemble du tableau et ne le traitez-vous pas au besoin dans la fonction?

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

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

37
C'est parce que je ne peux pas modifier call_me (). Il est défini dans une autre bibliothèque et il n'est pas possible de jouer avec l'API.
Robert

62
+1, car même s'il ne répond pas à la question d'origine, c'est probablement ce que recherchaient les 100 000 personnes et plus qui ont consulté cette page.
Ishikawa

Quelqu'un peut-il expliquer ce que fait la ligne "call_me (x)"? Il semble que ce soit un nom de fonction sans le mot-clé de fonction? Que fait-il exactement?
nagé

1
@swam C'est un appel à la call_mefonction. Il manque juste un point-virgule à la fin.
SantiBailors

@swam met en exécution la fonction call_me (params) déclarée.
Julio Rodriguez

43

En supposant que call_me est une fonction globale, vous ne vous attendez donc pas à ce qu'elle soit définie.

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


7

Comme l'avait répondu @KaptajnKold

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

Et vous n'avez pas non plus besoin de définir tous les paramètres de la fonction call_me. Vous pouvez simplement utiliserarguments

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

4
C'est une mauvaise pratique ... vous ne pourrez pas voir ce dont la fonction a besoin et tous les paramètres sont facultatifs si vous regardez la fonction.
Robin

3

Notez ceci

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

};

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

page 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>

peut appeler la fonction avec n'importe quel Args

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

ou

<body onmousemove="FollowMouse(d1)">

Cela fait clairement partie de la réponse. "arguments" est définitivement nécessaire pour récupérer le tableau après l'appel. Merci!
FlorianB

2

Les arguments de fonction peuvent également être des tableaux:

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

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

bien sûr, on peut également utiliser la propagation :

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

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


2

Lors de l'utilisation de l'opérateur d'étalement, nous devons noter qu'il doit s'agir du dernier ou du seul paramètre transmis. Sinon, cela échouera.

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

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

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

Si vous devez passer un tableau comme argument de départ, vous pouvez le faire:

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

1

vous pouvez utiliser l'opérateur d'étalement sous une forme plus basique

[].concat(...array)

dans le cas des fonctions qui renvoient des tableaux mais qui devraient passer comme arguments

Exemple:

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

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

0

La réponse a déjà été donnée, mais je veux juste donner mon morceau de gâteau. Ce que vous voulez réaliser s'appellemethod borrowing dans le contexte de JS, c'est-à-dire lorsque nous prenons une méthode d'un objet et l'appelons dans le contexte d'un autre objet. Il est assez courant de prendre des méthodes de tableau et de les appliquer aux arguments. Laisse moi te donner un exemple.

Nous avons donc une fonction de hachage "super" qui prend deux nombres comme argument et renvoie une chaîne de hachage "super sûre":

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

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

Jusqu'ici tout va bien, mais nous avons peu de problème avec l'approche ci-dessus, elle est contrainte, ne fonctionne qu'avec deux nombres, ce n'est pas dynamique, faisons-la fonctionner avec n'importe quel nombre et en plus vous n'avez pas à passer un tableau (vous pouvez si vous insistez encore). Ok, assez parlé, battons-nous!

La solution naturelle serait d'utiliser la arr.joinméthode:

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

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

Oh, mec. Malheureusement, cela ne fonctionnera pas. Parce que nous appelons hash (arguments) et arguments objet est à la fois itérable et semblable à un tableau, mais pas un vrai tableau. Que diriez-vous de l'approche ci-dessous?

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

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

L'astuce s'appelle method borrowing.

Nous empruntons une joinméthode à partir d'un tableau régulier [].join.et utilisons [].join.callpour l'exécuter dans le contexte de arguments.

Pourquoi ça marche?

En effet, l'algorithme interne de la méthode native arr.join(glue) est très simple.

Tiré de la spécification presque «tel quel»:

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.

Donc, techniquement, cela prend cela et joint ce [0], ce [1]… etc. ensemble. Il est intentionnellement écrit d'une manière qui permet tout ce qui ressemble à un tableau (ce n'est pas un hasard, de nombreuses méthodes suivent cette pratique). C'est pourquoi cela fonctionne aussi avecthis=arguments.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.