Przekazywanie argumentów do innej funkcji javascript

386

Próbowałem następujących bezskutecznie:

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

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

a(1,2,3);

W funkcji a mogę użyć słowa kluczowego arguments, aby uzyskać dostęp do tablicy argumentów, w funkcji b są one utracone. Czy istnieje sposób przekazywania argumentów do innej funkcji javascript, tak jak próbuję to zrobić?

Anders Nygaard
źródło
3
@ BobStein-VisiBone Zgoda. Dodatkowo zauważ, że argumentstak naprawdę nie jest to tablica (ale raczej obiekt, który implementuje semantykę podobną do tablicy ) i dlatego na pierwszy rzut oka nie jest całkowicie jasne, czy można jej używać w taki sam sposób, jak rzeczywistą tablicę.
Jules
@Jules nadal głosuje, aby ponownie otworzyć po tylu latach. Jaka jest odznaka za spalanie cennej pracy innych ludzi? Wiele z nich do obejrzenia.
Bob Stein

Odpowiedzi:

542

Użyj, .apply()aby mieć taki sam dostęp do argumentsfunkcji in b, jak to:

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

Możesz to przetestować tutaj .

Nick Craver
źródło
21
@Brett - Możesz skopiować go do tablicy, a następnie nim manipulować przed przekazaniem, na przykład:var copy = [].slice.call(arguments); <remove what you want> myFunc.apply(this, copy);
Nick Craver
18
ale użycie applytego może zepsuć zakres b(jeśli na przykład jest to jakaś wewnętrzna funkcja obiektu)
vsync
3
@vsync dobry punkt, ale problem jest łatwy do rozwiązania: przekaż obiekt jako pierwszy argument do zastosowania.
Tad Lispy
11
nie ma sensu używać razem „argumentów” i „argumentów” ...
koleś
3
Ale wtedy „to” może zostać zmienione na coś innego niż oryginał b.
trusktr
223

Operator rozsiewu

Operator rozkładania pozwala na rozwinięcie wyrażenia w miejscach, w których oczekuje się wielu argumentów (dla wywołań funkcji) lub wielu elementów (dla literałów tablicowych).

ECMAScript ES6 dodał nowy operator, który pozwala to zrobić w bardziej praktyczny sposób: ... Operator rozprzestrzeniania .

Przykład bez użycia applymetody:

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 Ten fragment kodu zwraca błąd składniowy, jeśli Twoja przeglądarka nadal używa ES5.

Od redakcji: Ponieważ zastosowań urywek console.log(), należy otworzyć konsolę JS w przeglądarce, aby zobaczyć wynik - nie będzie żadnego wynik w treści strony.

Wyświetli ten wynik:

Obraz przykładu argumentów operatora Spread

Krótko mówiąc, operator rozkładania może być używany do różnych celów, jeśli używasz tablic, więc może być również używany do argumentów funkcji, podobny przykład wyjaśniono w oficjalnych dokumentach: Parametry odpoczynku

Walter Chapilliquen - wZVanG
źródło
6
To bardzo miły operator i nie mogę się doczekać, aby z niego skorzystać. To się jednak jeszcze nie wydarzy. W tej chwili jedyną przeglądarką, która już obsługuje operatora rozprzestrzeniania, jest FF. Kompletne, aktualne dane znajdują się w tabeli kompatybilności: kangax.github.io/compat-table/es6/#spread_%28...%29_operator
TMG
10
Dlaczego nie należy go używać? Z Babelem można go stosunkowo łatwo przenosić, zyskujesz wszystkie nowe funkcje i znacznie większą kompatybilność ze starszymi przeglądarkami.
adgelbfish
Jest to lepsze niż pierwsze rozwiązanie, ponieważ działa w funkcji zdefiniowanej za pomocą operatora strzałki.
sarfata
Nie potrzebujesz ...argstej afunkcji. Możesz po prostu wykonać funkcję bez argumentów i przekazać je za bpomocą...arguments
cronoklee
1
Każdemu, kto czyta tę odpowiedź: w przeciwieństwie do komentarza @ cronoklee'S, wyraźnie określającego ...argsjako a„s wejście może być ważne, jeśli mają funkcje zagnieżdżone.
Arshia001
81

Wyjaśnienie, że żadna z pozostałych odpowiedzi nie dostarcza, jest takie, że oryginalne argumenty nadal dostępne, ale nie w pierwotnej pozycji w argumentsobiekcie.

argumentsObiekt zawiera jeden element za każdy parametr dostarczanego do funkcji. Podczas rozmowy telefonicznej apodać trzy argumenty: Numery 1, 2oraz, 3. Więc argumentszawiera [1, 2, 3].

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

Podczas rozmowy telefonicznej b, jednak zdać dokładnie jednego argumentu: a„s argumentsobiektu. Więc argumentszawiera [[1, 2, 3]](czyli jeden element, który ajest argumentsprzedmiotem, który ma właściwości zawierające oryginalne argumenty a).

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

a(1,2,3);

Jak pokazał @Nick, możesz użyć, applyaby podać ustawiony argumentsobiekt w wywołaniu.

Następujące wyniki osiągają ten sam wynik:

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

Ale applyjest właściwe rozwiązanie w ogólnym przypadku.

Wayne
źródło
Czy zawsze powinieneś przejść thisdo apply?
Flimm,
1
@ Flimm - tak, ponieważ argumenty są drugim argumentem, musi być coś dla pierwszego argumentu (może być zerowy ).
RobG
0

Spróbuj tego

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
źródło