web-dev-qa-db-de.com

Kann eine variable Anzahl von Argumenten an eine JavaScript-Funktion gesendet werden?

Ist es möglich, eine variable Anzahl von Argumenten aus einem Array an eine JavaScript-Funktion zu senden? 

var arr = ['a','b','c']

var func = function()
{
    // debug 
    alert(arguments.length);
    //
    for(arg in arguments)
        alert(arg);
}

func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d'
func(arr); // prints 1, then 'Array'

Ich habe kürzlich viel Python geschrieben und es ist ein wunderbares Muster, Varargs akzeptieren und versenden zu können. z.B.

def func(*args):
   print len(args)
   for i in args:
       print i

func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d'
func(*arr) // prints 4 which is what I want, then 'a','b','c','d'

Ist es in JavaScript möglich, ein Array zu senden, um als das Argument-Array zu behandeln? 

147
Fire Crow

Verwenden Sie apply :

var arr = ['a','b','c'];

var func = function() {
  alert(arguments.length);

  for(var i = 0; i < arguments.length; i++) {
    alert(arguments[i]);
  }

};

func.apply(null, arr);

Beachten Sie, dass null als erstes Argument von apply verwendet wird. Dadurch wird das Schlüsselwort this auf das globale Objekt (Fenster) in func gesetzt.

Beachten Sie auch, dass das Objekt arguments nicht wirklich ein Array ist. Sie können es folgendermaßen konvertieren:

var argsArray = Array.prototype.slice.call(arguments);

Und vielleicht ist es für Sie nützlich, dass Sie wissen, wie viele Argumente eine Funktion erwartet:

var test = function (one, two, three) {}; 
test.length == 3;

Sie können aber beliebig viele Argumente übergeben ...

168
CMS

Sie können beliebig viele Werte an jede Javascript-Funktion übergeben. Die explizit benannten Parameter erhalten die ersten Werte, ALLE Parameter werden jedoch im arguments -Array gespeichert.

Um das Argumenten-Array in "unpacked" -Form zu übergeben, können Sie apply (c.f. Functional Javascript ) verwenden:

var otherFunc = function() {
   alert(arguments.length); // Outputs: 10
}

var myFunc = function() {
  alert(arguments.length); // Outputs: 10
  otherFunc.apply(this, arguments);
}
myFunc(1,2,3,4,5,6,7,8,9,10);
68
danben

Die Operatoren splat und spread sind Teil von ES6, der geplanten nächsten Version von Javascript. Bisher unterstützt nur Firefox sie. Dieser Code funktioniert in FF16 +:

var arr = ['quick', 'brown', 'lazy'];

var sprintf = function(str, ...args)
{
    for (arg of args) {
        str = str.replace(/%s/, arg);
    }
    return str;
}

sprintf.apply(null, ['The %s %s fox jumps over the %s dog.', ...arr]);
sprintf('The %s %s fox jumps over the %s dog.', 'slow', 'red', 'sleeping');

Beachten Sie die awkard-Syntax für die Verteilung. Die übliche Syntax von sprintf('The %s %s fox jumps over the %s dog.', ...arr); lautet noch nicht unterstützt . eine ES6-Kompatibilitätstabelle finden Sie hier .

Beachten Sie auch die Verwendung von for...of , einem weiteren ES6-Zusatz. Die Verwendung von for...in für Arrays ist eine schlechte Idee .

21
Tgr

Ab ES2015 gibt es zwei Methoden.

Das arguments-Objekt

Dieses Objekt ist in Funktionen eingebaut und bezieht sich entsprechend auf die Argumente einer Funktion. Technisch gesehen handelt es sich jedoch nicht um ein Array. Typische Array-Operationen funktionieren daher nicht. Die empfohlene Methode ist, Array.from oder den Spread-Operator zu verwenden, um daraus ein Array zu erstellen.

Ich habe andere Antworten mit slice gesehen. Tu das nicht Es verhindert Optimierungen (Quelle: MDN ).

Array.from(arguments)
[...arguments]

Ich würde jedoch behaupten, dass arguments problematisch ist, weil es verbirgt, was eine Funktion als Eingabe akzeptiert. Eine arguments-Funktion wird normalerweise wie folgt geschrieben:

function mean(){
    let args = [...arguments];
    return args.reduce((a,b)=>a+b) / args.length;
}

Manchmal wird der Funktionsheader wie folgt geschrieben, um die Argumente C-artig zu dokumentieren:

function mean(/* ... */){ ... }

Das ist aber selten.

Warum ist dies problematisch? Nehmen Sie zum Beispiel C. C ist abwärtskompatibel mit einem alten Prä-ANSI-Dialekt der Sprache, die als K & R C bekannt ist. K & R C ermöglicht Funktionsprototypen eine leere Argumentliste.

int myFunction();
/* This function accepts unspecified parameters */

ANSI C bietet eine Möglichkeit für varargs (...) und void, um eine leere Argumentliste anzugeben.

int myFunction(void);
/* This function accepts no parameters */

Viele Leute deklarieren versehentlich Funktionen mit einer unspecified-Argumentliste (int myfunction();), wenn sie erwarten, dass die Funktion null Argumente verwendet. Dies ist technisch gesehen ein Fehler, da die Funktion will Argumente akzeptiert. Eine beliebige Anzahl von ihnen.

Eine richtige varargs-Funktion in C hat die Form:

int myFunction(int nargs, ...);

Und tatsächlich hat JavaScript etwas Ähnliches.

Spread Operator / Rest-Parameter

Ich habe dir eigentlich schon den Spread-Operator gezeigt.

...name

Es ist ziemlich vielseitig und kann auch in der Argumentliste einer Funktion ("rest parameters") verwendet werden, um Varargs auf eine gut dokumentierte Weise anzugeben:

function mean(...args){
    return args.reduce((a,b)=>a+b) / args.length;
}

Oder als Lambda-Ausdruck:

((...args)=>args.reduce((a,b)=>a+b) / args.length)(1,2,3,4,5); // 3

Ich bevorzuge den Spread-Operator. Es ist sauber und selbstdokumentierend.

8
Braden Best

Die apply-Funktion benötigt zwei Argumente. Das Objekt this wird an gebunden und die Argumente werden mit einem Array dargestellt.

some_func = function (a, b) { return b }
some_func.apply(obj, ["arguments", "are", "here"])
// "are"
7
August Lilleaas

Es wird der Operator splat genannt. Sie können dies in JavaScript mit apply tun:

var arr = ['a','b','c','d'];
var func = function() {
    // debug 
    console.log(arguments.length);
    console.log(arguments);
}
func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d'
func(arr); // prints 1, then 'Array'
func.apply(null, arr); 
5
Chandra Patni

Mit ES6 können Sie rest-Parameter für varagrs verwenden. Dies nimmt die Argumentliste und konvertiert sie in ein Array.

function logArgs(...args) {
    console.log(args.length)
    for(let arg of args) {
        console.log(arg)
    }
}
4

Dies ist ein Beispielprogramm zum Berechnen der Summe von Ganzzahlen für variable Argumente und von Array auf Ganzzahlen. Hoffe das hilft.

var CalculateSum = function(){
    calculateSumService.apply( null, arguments );
}

var calculateSumService = function(){
    var sum = 0;

    if( arguments.length === 1){
        var args = arguments[0];

        for(var i = 0;i<args.length; i++){
           sum += args[i]; 
        }
    }else{
        for(var i = 0;i<arguments.length; i++){
           sum += arguments[i]; 
        }        
    }

     alert(sum);

}


//Sample method call

// CalculateSum(10,20,30);         

// CalculateSum([10,20,30,40,50]);

// CalculateSum(10,20);
2
streak
(function(window) {
  var proxied = window.alert;
  window.alert = function() {
    return proxied.apply(window, arguments);
  };
}(this));

alert(13, 37);
2
yckart

Für diejenigen, die hierher umgeleitet wurden von Variable Anzahl von Argumenten von einer Funktion an eine andere übergeben (die nicht als Duplikat dieser Frage markiert werden sollte):

Wenn Sie versuchen, eine variable Anzahl von Argumenten von einer Funktion an eine andere zu übergeben, können Sie seit JavaScript 1.8.5 einfach apply() für die zweite Funktion aufrufen und den Parameter arguments übergeben:

var caller = function()
{
    callee.apply( null, arguments );
}

var callee = function()
{
    alert( arguments.length );
}

caller( "Hello", "World!", 88 ); // Shows "3".

Note: Das erste Argument ist der zu verwendende this-Parameter. Das Übergeben von null ruft die Funktion aus dem globalen Kontext auf, d. H. Als globale Funktion anstelle der Methode eines Objekts.

Gemäß diesem Dokument hat die ECMAScript 5-Spezifikation die apply()-Methode neu definiert, um ein "generisches Array-ähnliches Objekt" anstelle eines strengen Arrays zu verwenden. Somit können Sie die Liste arguments direkt an die zweite Funktion übergeben.

Getestet in Chrome 28.0, Safari 6.0.5 und IE 10. Probieren Sie es mit diesem JSFiddle aus.

1
andrewtc

Ja, Sie können die Variable nein übergeben. von Argumenten zu einer Funktion. Sie können apply verwenden, um dies zu erreichen.

Z.B.:

var arr = ["Hi","How","are","you"];

function applyTest(){
    var arg = arguments.length;
    console.log(arg);
}

applyTest.apply(null,arr);
0
Abhijit

Möchten Sie, dass Ihre Funktion auf ein Arrayargument oder auf variable Argumente reagiert? Wenn letzteres, versuchen Sie:

var func = function(...rest) {
  alert(rest.length);

  // In JS, don't use for..in with arrays
  // use for..of that consumes array's pre-defined iterator
  // or a more functional approach
  rest.forEach((v) => console.log(v));
};

Wenn Sie jedoch ein Array-Argument behandeln möchten

var fn = function(arr) {
  alert(arr.length);

  for(var i of arr) {
    console.log(i);
  }
};
0
Dev Yego