Übergeben Sie eine unbekannte Anzahl von Argumenten an die Javascript-Funktion

84

Gibt es eine Möglichkeit, eine unbekannte Anzahl von Argumenten zu übergeben, wie:

var print_names = function(names) {
    foreach(name in names) console.log(name); // something like this
}

print_names('foo', 'bar', 'baz');

Wie erhalte ich auch die Anzahl der übergebenen Argumente?

Ajsie
quelle
Bisher public override Antwort ist die einzige, die beschreibt , wie passieren eine unbekannte Anzahl von Argumenten (in einem Funktionsaufruf) (mit .apply). Die anderen zeigen, wie eine unbekannte Anzahl von Argumenten (aus der Funktion heraus) gelesen wird (mit arguments).
Ben J

Antworten:

146

ES3 (oder ES5 oder Oldschool Javascript)

Sie können über das magische argumentsObjekt, das sich ähnlich wie ein Array verhält, auf die Argumente zugreifen, die an eine beliebige Javascript-Funktion übergeben wurden . Die Verwendung argumentsIhrer Funktion würde so aussehen

var print_names = function() {
     for (var i=0; i<arguments.length; i++) console.log(arguments[i]);
}

Es ist wichtig zu beachten , dass argumentsist nicht ein Array. MDC enthält einige gute Dokumentationen: https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Functions#Using_the_arguments_object

Wenn Sie möchten , drehen argumentsin ein Array , so dass Sie Dinge tun können wie .slice(), .push()etc, verwenden Sie so etwas wie dieses:

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

ES6 / Typoskript

Es gibt einen besseren Weg! Die neue Rest Parameter Funktion hat den Rücken:

var print_names = function(...names) {
    for (let i=0; i<names.length; i++) console.log(names[i]);
}
ShZ
quelle
3
Vielen Dank für eine so detaillierte und gleichzeitig kurze + einfache Antwort :)
Mese
1
Der ES6-Verweis auf spread syntaxist hier völlig falsch. Das ist ein rest parameterBeispiel, das Sie gegeben haben. Gute Antwort, aber verwirrend, dass es alsspread
Drenai
Danke für deine Antwort! Ich fand dies ein hilfreicher Artikel, der erklärt, was passiert mit Array.prototype.slice.call(arguments): medium.com/@andrewsburke/…
AnnieP
22

ES6 / ES2015

Nutzen Sie die Restparametersyntax .

function printNames(...names) {
  console.log(`number of arguments: ${names.length}`);
  for (var name of names) {
    console.log(name);
  }
}

printNames('foo', 'bar', 'baz');

Es gibt drei Hauptunterschiede zwischen Ruheparametern und dem Argumentobjekt:

  • Restparameter sind nur diejenigen, denen kein separater Name zugewiesen wurde, während das Argumentobjekt alle an die Funktion übergebenen Argumente enthält.
  • Das Argumentobjekt ist kein reales Array, während Restparameter Array-Instanzen sind. Dies bedeutet, dass Methoden wie sort, map, forEach oder pop direkt darauf angewendet werden können.
  • Das Argument-Objekt verfügt über zusätzliche, für sich selbst spezifische Funktionen (wie die Eigenschaft callee).
RationalDev mag GoFundMonica
quelle
Dies ist absolut sinnvoll für die Webentwicklung, die normalerweise die gängige PHP-Syntax verwendet.
Dadan
13
var 
print_names = function() {
    console.log.apply( this, arguments );
};

print_names( 1, 2, 3, 4 );
öffentliche Außerkraftsetzung
quelle
7
function print_args() {
    for(var i=0; i<arguments.length; i++)
        console.log(arguments[i])
}
Gabi Purcaru
quelle
6

Es gibt ein verstecktes Objekt, das an jede Funktion in JavaScript übergeben wird arguments.

Sie würden nur verwenden arguments.length, um die Anzahl der an die Funktion übergebenen Argumente abzurufen.

Um die Argumente zu durchlaufen, verwenden Sie eine Schleife:

for(var i = arguments.length; i--) {
   var arg = arguments[i];
}

Beachten Sie, dass dies argumentskein echtes Array ist. Wenn Sie es also als Array benötigen, konvertieren Sie es folgendermaßen:

var args = Array.prototype.slice.call(arguments);
Jacob Relkin
quelle
3
Es genügt zu bemerken , dass es nicht ein „echter“ Array ist, ist es eine „Array-like“ ist Gegenstand (mit einigen besonderen Eigenschaften), aber „Array - Methoden“ auf , es zu benutzen, müssen Sie sie konvertieren, zB var args = Array.prototype.slice.call(arguments);, var args = Array.apply(null, arguments);usw. Es gibt viele Möglichkeiten ...
Christian C. Salvadó
4

arguments.length. Sie können eine for-Schleife verwenden.

(function () {
    for (var a = [], i = arguments.length; i--;) {
        a.push(arguments[i]);
    };
    return a;
})(1, 2, 3, 4, 5, 6, 7, 8)
meder omuraliev
quelle
@meder, ich liebe es, solche anonymen Funktionen zu verwenden. Schönes Beispiel! Vermissen Sie dort auch ein paar Semikolons?
Jacob Relkin
scheint so wie es ist gut zu laufen.
Meder Omuraliev
@meder, Semikolon Einfügung in JavaScript #ftf
Jacob Relkin
@meder, in der Tat, nur das Semikolon nach dem forBlock wird nicht wirklich benötigt, aber ich würde eines am Ende der letzten Zeile hinzufügen.
Christian C. Salvadó
1
@weng, es geht um FunctionExpressionvs FunctionDeclaration, überprüfen Sie diesen Artikel .
Christian C. Salvadó
2

Viel besser jetzt für ES6

function Example() {
    return {
        arguments: (...args) =>{
            args.map(a => console.log());
        }
    }
}

var exmpl = new Example();
exmpl.arguments(1, 2, 3, 'a', 'b', 'c');

ich hoffe das hilft

Santiago Posada
quelle
0

Ruheparameter in ES6

const example = (...args) => {
  for (arg in args) {
    console.log(arg);
  }
}

Hinweis: Sie können reguläre Parameter vor den restlichen Parametern übergeben

const example = (arg1, ...args) => {
  console.log(arg1);
  for (arg in args) {
    console.log(arg);
  }
}
Kurtis Streutker
quelle
0

Sie können den Spread / Rest-Operator verwenden, um Ihre Parameter in einem Array zu sammeln. Dann entspricht lengthder Wert des Arrays der Anzahl der Parameter, die Sie übergeben haben:

function foo(...names) {
    console.log(names);
    return names;
}

console.log(foo(1, 2, 3, 4).length);

Mit BabelJS habe ich die Funktion in oldschool JS konvertiert:

"use strict";

function foo() {
  for (var _len = arguments.length, names = new Array(_len), _key = 0; _key < _len; _key++) {
    names[_key] = arguments[_key];
  }

  console.log(names);
  return names;
}
Lajos Arpad
quelle
0

Sie können eine Funktion mit dem Spread / Rest-Operator erstellen und von da an haben Sie Ihr Ziel erreicht. Bitte werfen Sie einen Blick auf den Block unten.

const print_names = (...args) => args.forEach(x => console.log(x));
Mabulu
quelle
0

let x = function(){
  return [].slice.call(arguments);
};

console.log(x('a','b','c','d'));

Sekhar552
quelle
-4

Ich mache das gerne:

Dies hilft nicht, wenn Sie die Anzahl der Argumente nicht kennen, aber es hilft, wenn Sie sich nicht an die Reihenfolge erinnern möchten.

/**
 *  @param  params.one        A test parameter
 *  @param  params.two        Another one  
 **/
function test(params) {

    var one = params.one;
    if(typeof(one) == 'undefined') {
        throw new Error('params.one is undefined');
    }

    var two = params.two;
    if(typeof(two) == 'undefined') {
        throw new Error('params.two is undefined');
    }
}
Colin Sullivan
quelle
1
Die Frage betraf eine unbekannte Anzahl von Argumenten.
Entwurf durch Adrian