web-dev-qa-db-fra.com

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

J'aimerais appeler une fonction utilisant un tableau en tant que 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 un meilleur moyen de passer le contenu de x dans call_me()?

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

Voir la documentation MDN pour Function.prototype.apply() .


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

call_me(...args);
363
KaptajnKold

Pourquoi ne passez-vous pas tout le tableau et ne le traitez 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])
  }
}
86
Karl Johan

En supposant que call_me soit une fonction globale, vous ne vous attendez pas à ce que cela soit défini.

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

Dans la norme ES6, il existe un nouvel opérateur spread... qui fait exactement cela.

call_me(...x)

Il est supporté par tous les principaux navigateurs sauf IE.

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

36
BoltKey

Comme @KaptajnKold avait répondu

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 pour la fonction call_me ... vous pouvez simplement utiliser arguments

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

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 une fonction avec n'importe quel Args

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

ou

<body onmousemove="FollowMouse(d1)">
3
ali.b.y

Les arguments de fonction peuvent aussi ê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 aussi utiliser spread :

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

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

1
vsync

En utilisant l'opérateur spread, il faut noter que ce doit être le dernier ou le seul paramètre passé. Sinon, ça va échouer.

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 avez besoin de passer un tableau comme argument de départ, vous pouvez faire:

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

La réponse était déjà donnée, mais je veux juste donner ma part du gâteau. Ce que vous voulez réaliser s'appelle method borrowing dans le contexte de JS, 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 à des arguments. Laisse moi te donner un exemple. 

Nous avons donc une fonction de "super" hachage qui prend deux nombres en argument et renvoie la chaîne de hachage "super sécurisée":

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

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

Jusqu'ici tout va bien, mais l'approche ci-dessus ne pose pas de problème, elle est contrainte, ne fonctionne qu'avec deux nombres, ce n'est pas dynamique, faisons-le fonctionner avec n'importe quel nombre si vous insistez encore). Ok, assez parlé, luttons!

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

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

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

Oh, mec. Malheureusement, ça ne marchera 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 méthode join à un tableau régulier [].join. et utilisons [].join.call pour l'exécuter dans le contexte de arguments.

Pourquoi ça marche?

C’est parce que 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, il prend cela et rejoint ce [0], ce [1]… etc. Il est intentionnellement écrit d’une manière qui permette à tout tableau de ressembler à ceci (ce n’est pas une coïncidence, de nombreuses méthodes suivent cette pratique). C’est pourquoi cela fonctionne aussi avec this=arguments.

0
Humoyun

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

[].concat(...array)

dans le cas de fonctions qui retournent des tableaux mais sont supposées passer comme arguments

Exemple:

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

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

0
rman