Przekazywanie tablicy jako parametru funkcji w JavaScript

290

Chciałbym wywołać funkcję przy użyciu tablicy jako parametrów:

const x = ['p0', 'p1', 'p2'];
call_me(x[0], x[1], x[2]); // I don't like it

function call_me (param0, param1, param2 ) {
  // ...
}

Czy istnieje lepszy sposób przekazywania treści od xdo call_me()?

Robert
źródło

Odpowiedzi:

421
const args = ['p0', 'p1', 'p2'];
call_me.apply(this, args);

Zobacz dokumentację MDN dla Function.prototype.apply().


Jeśli środowisko obsługuje ECMAScript 6, możesz zamiast tego użyć argumentu rozprzestrzeniania :

call_me(...args);
KaptajnKold
źródło
9
Na marginesie, jeśli ktoś chce zamiast tego przekazać tablicę asocjacyjną (nazwane klucze), użyj obiektu. Pochodzenie z PHP (i zawsze prowadził do tego wątku przez google) zajęło mi to trochę czasu, aby dowiedzieć się. Następnie możesz przekazać cały obiekt jako parametr. w3schools.com/js/js_objects.asp
timhc22
Dziękujemy za wskazanie argumentu „rozprzestrzeniania się”! Nie wiedziałem o tym.
Thomas An,
@timhc - twój komentarz do notatki jest intrygujący, ale nie mogę go przeanalizować (jestem jaob skryptem noob pracującym przez kilka samouczków). W JS tablica asocjacyjna jest obiektem według kilku samouczków.
NateT
@ timhc22, a gdy używasz obiektu json do przekazania jako parametru do funkcji, nie zapomnij o zniszczeniu parametru dla lepszej czytelności
Muhammad Omer Aslam,
113

Dlaczego nie przekazujesz całej tablicy i nie przetwarzasz jej w razie potrzeby wewnątrz funkcji?

var x = [ 'p0', 'p1', 'p2' ]; 
call_me(x);

function call_me(params) {
  for (i=0; i<params.length; i++) {
    alert(params[i])
  }
}
Karl Johan
źródło
37
To dlatego, że nie mogę zmodyfikować call_me (). Jest zdefiniowany w jakiejś innej bibliotece i nie można zadzierać z API.
Robert
62
+1, ponieważ chociaż nie odpowiada na pierwotne pytanie, prawdopodobnie tego szukało ponad 100 000 osób, które oglądały tę stronę.
Ishikawa,
Czy ktoś może wyjaśnić, co robi linia „call_me (x)”? Wygląda na to, że jest to nazwa funkcji bez słowa kluczowego function? Co to właściwie robi?
pływał
1
@swam Jest to wywołanie call_mefunkcji. Na końcu brakuje mu średnika.
SantiBailors
@swam realizuje zadeklarowaną funkcję call_me (params).
Julio Rodriguez
43

Zakładając, że call_me jest funkcją globalną, więc nie oczekujesz, że zostanie to ustawione.

var x = ['p0', 'p1', 'p2'];
call_me.apply(null, x);
plexer
źródło
7

Jak odpowiedział @KaptajnKold

var x = [ 'p0', 'p1', 'p2' ];
call_me.apply(this, x);

Nie musisz też definiować wszystkich parametrów dla funkcji call_me. Możesz po prostu użyćarguments

function call_me () {
    // arguments is a array consisting of params.
    // arguments[0] == 'p0',
    // arguments[1] == 'p1',
    // arguments[2] == 'p2'
}
徐 竟 峰
źródło
4
To taka zła praktyka ... nie będziesz w stanie zobaczyć, czego potrzebuje funkcja, a wszystkie parametry są opcjonalne, jeśli spojrzysz na funkcję.
Robin
3

Zauważ to

function FollowMouse() {
    for(var i=0; i< arguments.length; i++) {
        arguments[i].style.top = event.clientY+"px";
        arguments[i].style.left = event.clientX+"px";
    }

};

// ---------------------------

strona HTML

<body onmousemove="FollowMouse(d1,d2,d3)">

<p><div id="d1" style="position: absolute;">Follow1</div></p>
<div id="d2" style="position: absolute;"><p>Follow2</p></div>
<div id="d3" style="position: absolute;"><p>Follow3</p></div>


</body>

może wywoływać funkcję z dowolnymi argumentami

<body onmousemove="FollowMouse(d1,d2)">

lub

<body onmousemove="FollowMouse(d1)">
ali.by
źródło
To wyraźnie część odpowiedzi. „argumenty” są zdecydowanie potrzebne do odzyskania tablicy po wywołaniu. Dzięki!
FlorianB
2

Argumentami funkcji mogą być również tablice:

function foo([a,b,c], d){
  console.log(a,b,c,d);
}

foo([1,2,3], 4)

oczywiście można również użyć spread :

function foo(a, b, c, d){
  console.log(a, b, c, d);
}

foo(...[1, 2, 3], 4)

vsync
źródło
2

Korzystając z operatora rozkładania, musimy zauważyć, że musi to być ostatni lub jedyny przekazany parametr. W przeciwnym razie zawiedzie.

function callMe(...arr){ //valid arguments
    alert(arr);
}

function callMe(name, ...arr){ //valid arguments
    alert(arr);
}

function callMe(...arr, name){ //invalid arguments
    alert(arr);
}

Jeśli potrzebujesz przekazać tablicę jako argument początkowy, możesz:

function callMe(arr, name){
    let newArr = [...arr];
    alert(newArr);
}
Naba
źródło
1

możesz użyć operatora spreadu w bardziej podstawowej formie

[].concat(...array)

w przypadku funkcji, które zwracają tablice, ale powinny przejść jako argumenty

Przykład:

function expectArguments(...args){
  return [].concat(...args);
}

JSON.stringify(expectArguments(1,2,3)) === JSON.stringify(expectArguments([1,2,3]))
rman
źródło
0

Odpowiedź była już udzielona, ​​ale chcę tylko dać bułkę z masłem. To, co chcesz osiągnąć, nazywa sięmethod borrowing w kontekście JS, gdy pobieramy metodę z obiektu i wywołujemy ją w kontekście innego obiektu. Dość powszechne jest stosowanie metod tablicowych i stosowanie ich do argumentów. Dam ci przykład.

Mamy więc funkcję „super” mieszającą, która przyjmuje jako argument dwie liczby i zwraca ciąg „super bezpieczny”:

function hash() {
  return arguments[0]+','+arguments[1];
}

hash(1,2); // "1,2" whoaa

Jak dotąd tak dobrze, ale nie mamy problemu z powyższym podejściem, jest ono ograniczone, działa tylko z dwiema liczbami, co nie jest dynamiczne, zróbmy to z dowolną liczbą i dodatkowo nie musisz przechodzić przez tablicę (możesz jeśli nadal nalegasz). Ok, dość gadania, walczmy!

Naturalnym rozwiązaniem byłoby zastosowanie arr.joinmetody:

function hash() {
  return arguments.join();
}

hash(1,2,4,..); //  Error: arguments.join is not a function

O stary. Niestety to nie zadziała. Ponieważ nazywamy skrót (argumenty), a obiekt argumentów jest iterowalny i podobny do tablicy, ale nie jest prawdziwą tablicą. Co powiesz na poniższe podejście?

function hash() {
  return [].join.call(arguments);
}

hash(1,2,3,4); // "1,2,3,4" whoaa

Trik nazywa się method borrowing.

Pożyczamy joinmetodę ze zwykłej tablicy [].join.i używamy [].join.calldo jej uruchomienia w kontekściearguments .

Dlaczego to działa?

Jest tak, ponieważ wewnętrzny algorytm metody natywnej arr.join(glue) jest bardzo prosty.

Wzięty ze specyfikacji prawie „tak jak jest”:

Let glue be the first argument or, if no arguments, then a comma ",".
Let result be an empty string.
Append this[0] to result.
Append glue and this[1].
Append glue and this[2].
Do so until this.length items are glued.
Return result.

Więc technicznie wymaga tego i łączy to [0], to [1]… itd. Razem. Jest celowo napisany w sposób, który pozwala na dowolną tablicę (nie jest to przypadek, wiele metod stosuje się do tej praktyki). Dlatego też działa zthis=arguments.

Humoyun Ahmad
źródło