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()?

Robert
la source

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);
KaptajnKold
la source
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])
  }
}
Karl Johan
la source
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);
plexer
la source
41

Dans la norme ES6, il y a un nouvel opérateur de propagation ... qui fait exactement cela.

call_me(...x)

Il est pris en charge par tous les principaux navigateurs, à l'exception d'IE.

L'opérateur d'étalement peut faire beaucoup d'autres choses utiles, et la documentation liée fait un très bon travail pour le montrer.

BoltKey
la source
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'
}
徐 竟 峰
la source
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)">
ali.by
la source
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)

vsync
la source
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);
}
Naba
la source
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]))
rman
la source
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.

Humoyun Ahmad
la source