Czy możliwe jest wysłanie zmiennej liczby argumentów do funkcji JavaScript?

Czy możliwe jest wysłanie zmiennej liczby argumentów do funkcji JavaScript z tablicy?

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'

Ostatnio napisałem dużo Pythona i jest to wspaniały wzór, aby móc zaakceptować varargs i wysłać je. np.

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'

Czy w JavaScript możliwe jest wysłanie tablicy traktowanej jako tablica argumentów?

Author: Brendan Long, 2009-12-24

11 answers

Użyj zastosuj :

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);

Zauważ, że null jest używany jako pierwszy argument apply, który ustawi słowo kluczowe this na globalny obiekt (okno) wewnątrz func.

Należy również zauważyć, że arguments obiekt tak naprawdę nie jest tablicą, można go przekonwertować przez:

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

I może jest dla Ciebie przydatne, że możesz wiedzieć, ile argumentów oczekuje funkcja:

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

Ale w każdym razie możesz przekazać dowolną liczbę argumentów...

 164
Author: CMS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-07 20:45:40

Możesz przekazać dowolną liczbę wartości do dowolnej funkcji javascript. Jawnie nazwane parametry otrzymają kilka pierwszych wartości, ale wszystkie parametry zostaną zapisane w tablicy argumentów.

Aby przekazać tablicę argumentów w postaci "rozpakowanej", możesz użyć apply, jak tak (c. f. Functional Javascript):

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);
 64
Author: danben,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-04 13:21:48

Operatorysplat ispread są częścią ES6, planowanej kolejnej wersji Javascript. Do tej pory tylko Firefox je obsługuje. Ten kod działa w 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');

Zwróć uwagę na awkard składni dla rozprzestrzeniania. Standardowa składnia sprintf('The %s %s fox jumps over the %s dog.', ...arr); to nie jest jeszcze obsługiwana. Możesz znaleźć tabelę zgodności ES6 tutaj .

Zwróć również uwagę na użycie for...of, kolejny dodatek ES6. Używanie for...in dla tablic jest złym pomysłem .

 17
Author: Tgr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:54

Funkcja apply pobiera dwa argumenty; obiekt this będzie powiązany z, a argumenty reprezentowane za pomocą tablicy.

some_func = function (a, b) { return b }
some_func.apply(obj, ["arguments", "are", "here"])
// "are"
 6
Author: August Lilleaas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-24 17:11:20

Nazywa się operatorem splat. Możesz to zrobić w JavaScript używając apply:

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
Author: Chandra Patni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-16 17:38:33

Istnieją dwie metody od ES2015.

Obiekt arguments

Ten obiekt jest wbudowany w funkcje i odnosi się odpowiednio do argumentów funkcji. Technicznie nie jest to jednak tablica, więc typowe operacje na tablicy nie będą na niej działać. Sugerowaną metodą jest użycie Array.from lub operatora spread do utworzenia z niego tablicy.

Widziałem inne odpowiedzi, używając slice. Nie rób tego. Zapobiega optymalizacji (źródło: MDN ).

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

Argumentowałbym jednak, że arguments jest problematyczne, ponieważ ukrywa to, co funkcja przyjmuje jako dane wejściowe. Funkcja arguments jest zazwyczaj zapisywana w następujący sposób:

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

Czasami nagłówek funkcji jest zapisywany w następujący sposób, aby udokumentować argumenty w sposób podobny do C:

function mean(/* ... */){ ... }
Ale to rzadkość.

Jeśli chodzi o to, dlaczego jest problematyczne, Weźmy na przykład C. C jest wstecznie kompatybilny ze starożytnym przed ANSI dialekt języka znanego ponieważ K & R C. K & R C pozwala prototypom funkcji mieć pustą listę argumentów.

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

ANSI C zapewnia możliwość varargs (...), i void aby określić pustą listę argumentów.

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

Wiele osób niechcący deklaruje funkcje z unspecified listą argumentów (int myfunction();), kiedy oczekują, że funkcja pobierze zero argumentów. Jest to technicznie błąd, ponieważ funkcja będzie akceptować argumenty. Dowolna ich liczba.

A proper varargs function in C przyjmuje postać:

int myFunction(int nargs, ...);

I JavaScript rzeczywiście ma coś podobnego do tego.

Operator Spreadu / Parametry Odpoczynku

Pokazałem ci już operatora spreadu.

...name
Jest dość uniwersalny i może być również używany w liście argumentów funkcji ("parametry rest"), aby określić varargs w ładnie udokumentowany sposób:]}
function mean(...args){
    return args.reduce((a,b)=>a+b) / args.length;
}

Lub jako wyrażenie lambda:

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

Zdecydowanie wolę spread centrala. Jest czysty i samokontroli.

 5
Author: Braden Best,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-29 03:38:29

Jest to przykładowy program do obliczania sumy liczb całkowitych dla zmiennych argumentów i tablicy na liczbach całkowitych. Mam nadzieję, że to pomoże.

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
Author: streak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-08 16:48:18
(function(window) {
  var proxied = window.alert;
  window.alert = function() {
    return proxied.apply(window, arguments);
  };
}(this));

alert(13, 37);
 2
Author: yckart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-31 15:23:19

Dla tych, którzy zostali przekierowani z przekazując zmienną liczbę argumentów z jednej funkcji do drugiej (co powinno Nie być oznaczone jako DUPLIKAT tego pytania):

Jeśli próbujesz przekazać zmienną liczbę argumentów z jednej funkcji do drugiej, od wersji JavaScript 1.8.5 możesz po prostu wywołać {[1] } na drugiej funkcji i przekazać w parametrze arguments:

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

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

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

Uwaga: pierwszym argumentem jest parametr this. Przechodząc null wywoła funkcję z kontekstu globalnego, tzn. jako funkcję globalną zamiast metody jakiegoś obiektu.

Zgodnie z tym dokumentem , Specyfikacja ECMAScript 5 przedefiniowała metodę apply(), aby przyjmować dowolny "ogólny obiekt podobny do tablicy", zamiast ściśle tablicy. W ten sposób możesz bezpośrednio przekazać arguments listę do drugiej funkcji.

Testowane w Chrome 28.0, Safari 6.0.5 i IE 10. Wypróbuj to z tym JSFiddle .
 1
Author: andrewtc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:30:49

Z ES6 możesz użyć rest parameters dla varagrs. Pobiera listę argumentów i konwertuje ją do tablicy.

function logArgs(...args) {
    console.log(args.length)
    for(let arg of args) {
        console.log(arg)
    }
}
 1
Author: theres.yer.problem,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-21 23:10:51

Tak możesz podać zmienną nie. argumentów do funkcji. Możesz użyć apply, aby to osiągnąć.

Np.:

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

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

applyTest.apply(null,arr);
 0
Author: Abhijit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-31 13:47:15