Weitergabe von Argumenten an eine andere Javascript-Funktion

386

Ich habe Folgendes ohne Erfolg versucht:

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

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

a(1,2,3);

In Funktion a kann ich das Argument-Schlüsselwort verwenden, um auf ein Array von Argumenten zuzugreifen. In Funktion b gehen diese verloren. Gibt es eine Möglichkeit, Argumente an eine andere Javascript-Funktion zu übergeben, wie ich es versuche?

Anders Nygaard
quelle
3
@ BobStein-VisiBone Einverstanden. Beachten Sie außerdem, dass argumentses sich nicht um ein Array handelt (sondern um ein Objekt, das eine Array-ähnliche Semantik implementiert ). Daher ist auf den ersten Blick nicht ganz klar, ob es auf die gleiche Weise wie ein tatsächliches Array verwendet werden kann.
Jules
@Jules stimmen nach all den Jahren immer noch für die Wiedereröffnung . Was ist das Abzeichen, um die wertvolle Arbeit anderer Menschen zu verbrennen? Viele von denen, um herumzugehen.
Bob Stein

Antworten:

542

Verwenden Sie .apply()diese Option , um denselben Zugriff auf die argumentsFunktion zu haben b:

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

Sie können es hier testen .

Nick Craver
quelle
21
@Brett - Sie können es in ein Array kopieren und dann manipulieren, bevor Sie es weitergeben, zum Beispiel:var copy = [].slice.call(arguments); <remove what you want> myFunc.apply(this, copy);
Nick Craver
18
Aber wenn Sie applydies verwenden, kann dies den Umfang von b(wenn es sich beispielsweise um eine innere Funktion eines Objekts handelt)
vsync
3
@vsync guter Punkt, aber das Problem ist leicht zu lösen: Übergeben Sie das Objekt als erstes anzuwendendes Argument.
Tad Lispy
11
macht keinen Sinn, "Argumente" und "Argumente" zusammen zu verwenden ...
Alter
3
Aber dann könnte das "Dies" in etwas anderes als das Original von B geändert werden.
trusktr
223

Spread-Operator

Mit dem Spread-Operator kann ein Ausdruck an Stellen erweitert werden, an denen mehrere Argumente (für Funktionsaufrufe) oder mehrere Elemente (für Array-Literale) erwartet werden.

ECMAScript ES6 hat einen neuen Operator hinzugefügt, mit dem Sie dies praktischer tun können: ... Spread Operator .

Beispiel ohne Verwendung der applyMethode:

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 Dieses Snippet gibt einen Syntaxfehler zurück, wenn Ihr Browser weiterhin ES5 verwendet.

Anmerkung des Herausgebers: Da das Snippet verwendet wird console.log(), müssen Sie die JS-Konsole Ihres Browsers öffnen, um das Ergebnis anzuzeigen. Es wird kein In-Page-Ergebnis angezeigt .

Dieses Ergebnis wird angezeigt:

Beispiel für ein Beispiel eines Spread-Operators

Kurz gesagt, der Spread-Operator kann für verschiedene Zwecke verwendet werden, wenn Sie Arrays verwenden. Er kann also auch für Funktionsargumente verwendet werden. Ein ähnliches Beispiel finden Sie in den offiziellen Dokumenten: Rest-Parameter

Walter Chapilliquen - wZVanG
quelle
6
Dies ist ein sehr netter Operator und ich freue mich sehr darauf, ihn zu verwenden. Es wird jedoch noch nicht passieren. Der einzige Browser, der den Spread-Operator bereits unterstützt, ist derzeit FF. In der Kompatibilitätstabelle finden Sie vollständige, aktuelle Daten: kangax.github.io/compat-table/es6/#spread_%28...%29_operator
TMG
10
Warum sollte es nicht verwendet werden? Es ist relativ einfach, mit babel zu transpilieren, Sie erhalten alle neuen Funktionen und viel mehr Kompatibilität mit älteren Browsern.
Adgelbfish
Dies ist besser als die erste Lösung, da sie in Funktionen funktioniert, die mit dem Pfeiloperator definiert wurden.
Sarfata
Sie brauchen nicht ...argsin der aFunktion. Sie können einfach eine Funktion ohne Argumente b...arguments
erstellen
1
Für jeden, der diese Antwort liest: Im Gegensatz zu @ cronoklees Kommentar kann es wichtig sein , explizit ...argsals aEingabe anzugeben , wenn Sie verschachtelte Funktionen haben.
Arshia001
81

Die Erklärung , dass keiner der anderen Antworten liefern , ist , dass die ursprünglichen Argumente sind immer noch vorhanden, aber nicht in der ursprünglichen Position in dem argumentsObjekt.

Das argumentsObjekt enthält ein Element für jeden Aktualparameter, der der Funktion zur Verfügung gestellt wird. Wenn Sie anrufen aversorgen Sie drei Argumente: die Zahlen 1, 2und, 3. Also argumentsenthält [1, 2, 3].

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

Wenn Sie jedoch aufrufen b, übergeben Sie genau ein Argument: adas argumentsObjekt. So argumentsenthält [[1, 2, 3]](dh ein Element, das ist a‚s - argumentsObjekt, das Objekte enthält , die ursprünglichen Argumente hat a).

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

a(1,2,3);

Wie @Nick gezeigt hat, können Sie applyein festgelegtes argumentsObjekt im Aufruf bereitstellen .

Folgendes führt zum gleichen Ergebnis:

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

Ist applyaber im allgemeinen Fall die richtige Lösung.

Wayne
quelle
Sollten Sie immer passieren thiszu apply?
Flimm
1
@ Flimm - ja, da die Argumente das zweite Argument sind, muss für das erste Argument etwas vorhanden sein (es kann null sein ).
RobG
0

Versuche dies

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
quelle