Passer des arguments à une autre fonction javascript

386

J'ai essayé ce qui suit sans succès:

function a(args){
    b(arguments);
}

function b(args){
    // arguments are lost?
}

a(1,2,3);

Dans la fonction a, je peux utiliser le mot-clé arguments pour accéder à un tableau d'arguments, dans la fonction b ceux-ci sont perdus. Existe-t-il un moyen de passer des arguments à une autre fonction javascript comme j'essaie de le faire?

Anders Nygaard
la source
3
@ BobStein-VisiBone D'accord. De plus, notez qu'il argumentsne s'agit pas réellement d' un tableau (mais plutôt d'un objet qui implémente une sémantique de type tableau ) et qu'il n'est donc pas tout à fait clair à première vue s'il peut être utilisé de la même manière qu'un tableau réel.
Jules
@Jules vote toujours pour rouvrir après toutes ces années. Quel est l'insigne pour brûler le précieux travail des autres? Beaucoup de ceux à faire le tour.
Bob Stein

Réponses:

542

Utilisez .apply()pour avoir le même accès à argumentsen fonction b, comme ceci:

function a(){
    b.apply(null, arguments);
}
function b(){
   alert(arguments); //arguments[0] = 1, etc
}
a(1,2,3);​

Vous pouvez le tester ici .

Nick Craver
la source
21
@Brett - Vous pouvez le copier dans un tableau puis le manipuler avant de le transmettre, par exemple:var copy = [].slice.call(arguments); <remove what you want> myFunc.apply(this, copy);
Nick Craver
18
mais utiliser applycomme ça pourrait bousiller la portée de b(si c'est une fonction interne d'un objet par exemple)
vsync
3
@vsync bon point, mais le problème est facile à résoudre: passez l'objet comme premier argument à appliquer.
Tad Lispy
11
n'a pas de sens d'utiliser "args" et "arguments" ensemble ...
mec
3
Mais alors le "ceci" pourrait être changé en quelque chose d'autre que l'original de b ceci.
trusktr
223

Opérateur de diffusion

L'opérateur spread permet à une expression d'être développée dans des endroits où plusieurs arguments (pour les appels de fonction) ou plusieurs éléments (pour les littéraux de tableau) sont attendus.

ECMAScript ES6 a ajouté un nouvel opérateur qui vous permet de le faire de manière plus pratique: ... Spread Operator .

Exemple sans utiliser la applyméthode:

function a(...args){
  b(...args);
  b(6, ...args, 8) // You can even add more elements
}
function b(){
  console.log(arguments)
}

a(1, 2, 3)

Note Cet extrait renvoie une erreur de syntaxe si votre navigateur utilise toujours ES5.

Note de l'éditeur: Étant donné que l'extrait de code utilise console.log(), vous devez ouvrir la console JS de votre navigateur pour voir le résultat - il n'y aura aucun résultat sur la page.

Il affichera ce résultat:

Image de l'exemple des arguments de l'opérateur Spread

En bref, l'opérateur de propagation peut être utilisé à des fins différentes si vous utilisez des tableaux, il peut donc également être utilisé pour des arguments de fonction, vous pouvez voir un exemple similaire expliqué dans les documents officiels: Paramètres de repos

Walter Chapilliquen - wZVanG
la source
6
C'est un très bon opérateur et j'ai vraiment hâte de l'utiliser. Cependant, cela n'arrivera pas encore. Le seul navigateur qui prend déjà en charge l'opérateur de propagation est FF pour le moment. Consultez le tableau de compatibilité pour des données complètes et à jour: kangax.github.io/compat-table/es6/#spread_%28...%29_operator
TMG
10
Pourquoi ne devrait-il pas être utilisé? Il est relativement facile à transpiler avec babel, vous obtenez toutes les nouvelles fonctionnalités et beaucoup plus de compatibilité avec les anciens navigateurs.
adgelbfish
C'est mieux que la première solution car elle fonctionne en fonction définie avec l'opérateur flèche.
sarfata
Vous n'avez pas besoin ...argsde la afonction. Vous pouvez simplement créer une fonction sans arguments et les transmettre à bwith...arguments
cronoklee
1
Pour tous ceux qui lisent cette réponse: Contrairement au commentaire de @ cronoklee, spécifier explicitement l' entrée ...argsas apeut être important si vous avez des fonctions imbriquées.
Arshia001
81

L'explication qu'aucune des autres réponses ne fournit est que les arguments d'origine sont toujours disponibles, mais pas dans la position d'origine dans l' argumentsobjet.

L' argumentsobjet contient un élément pour chaque paramètre réel fourni à la fonction. Lorsque vous appelez avous fournir trois arguments: les chiffres 1, 2et, 3. Donc, argumentscontient [1, 2, 3].

function a(args){
    console.log(arguments) // [1, 2, 3]
    b(arguments);
}

bCependant, lorsque vous appelez , vous passez exactement un argument: al' argumentsobjet de. argumentsContient donc [[1, 2, 3]](c'est-à-dire un élément, qui est al' argumentsobjet, qui a des propriétés contenant les arguments d'origine a).

function b(args){
    // arguments are lost?
    console.log(arguments) // [[1, 2, 3]]
}

a(1,2,3);

Comme l'a démontré @Nick, vous pouvez utiliser applypour fournir un argumentsobjet défini dans l'appel.

Ce qui suit obtient le même résultat:

function a(args){
    b(arguments[0], arguments[1], arguments[2]); // three arguments
}

Mais applyc'est la bonne solution dans le cas général.

Wayne
la source
Faut-il toujours passer thisà apply?
Flimm
1
@ Flimm - oui, puisque les arguments sont le deuxième argument, il doit y avoir quelque chose pour le premier argument (il peut être nul ).
RobG
0

essaye ça

function global_func(...args){
  for(let i of args){
    console.log(i)
  }
}


global_func('task_name', 'action', [{x: 'x'},{x: 'x'}], {x: 'x'}, ['x1','x2'], 1, null, undefined, false, true)




//task_name
//action
//(2) [{...},
//    {...}]
//    {
//        x:"x"
//    }
//(2) [
//        "x1",
//        "x2"
//    ]
//1
//null
//undefined
//false
//true
//func
Jaber Alshami
la source