Melewati array sebagai parameter fungsi dalam JavaScript

291

Saya ingin memanggil fungsi menggunakan array sebagai parameter:

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

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

Apakah ada cara yang lebih baik lewat isi xdalam call_me()?

Robert
sumber

Jawaban:

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

Lihat dokumen MDN untuk Function.prototype.apply().


Jika lingkungan mendukung ECMAScript 6, Anda dapat menggunakan argumen sebaran sebagai gantinya:

call_me(...args);
KaptajnKold
sumber
9
Sebagai catatan tambahan, jika ada yang ingin meneruskan array asosiatif (tombol bernama), gunakan objek. Berasal dari PHP (dan selalu mengarah ke utas ini oleh google), saya butuh waktu untuk mencari tahu. Anda dapat melewatkan seluruh objek sebagai parameter. w3schools.com/js/js_objects.asp
timhc22
Terima kasih telah menunjukkan argumen 'spread'! Tidak tahu tentang itu.
Thomas An
@timhc - komentar sampingan Anda menarik, tetapi saya tidak dapat menguraikannya (saya adalah javascript noob yang bekerja melalui beberapa tutorial). Di JS, array asosiatif adalah objek menurut beberapa tutorial.
NateT
@ timhc22, dan ketika menggunakan objek json untuk meneruskan sebagai parameter ke fungsi jangan lupa Penghancuran Parameter untuk keterbacaan yang lebih baik
Muhammad Omer Aslam
113

Mengapa Anda tidak melewatkan seluruh array dan memprosesnya sesuai kebutuhan di dalam fungsi?

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

function call_me(params) {
  for (i=0; i<params.length; i++) {
    alert(params[i])
  }
}
Karl Johan
sumber
37
Itu karena saya tidak dapat memodifikasi call_me (). Ini didefinisikan di beberapa perpustakaan lain dan tidak mungkin untuk mengacaukan dengan API.
Robert
62
Memberi +1 karena meskipun tidak menjawab pertanyaan awal, mungkin yang dicari 100K + orang yang melihat halaman ini.
Ishikawa
Adakah yang bisa menjelaskan apa yang dilakukan baris "call_me (x)"? Sepertinya itu adalah nama fungsi tanpa fungsi kata kunci? Apa sebenarnya yang dilakukannya?
berenang
1
@swam Ini adalah panggilan ke call_mefungsi. Itu hanya tidak memiliki titik koma di akhir.
SantiBailors
@swam itu sedang menjalankan fungsi call_me (params) yang dinyatakan.
Julio Rodriguez
43

Dengan anggapan bahwa call_me adalah fungsi global, jadi Anda tidak berharap ini disetel.

var x = ['p0', 'p1', 'p2'];
call_me.apply(null, x);
plekser
sumber
41

Dalam standar ES6 ada operator spread baru ...yang melakukan hal itu.

call_me(...x)

Ini didukung oleh semua browser utama kecuali untuk IE.

Operator penyebaran dapat melakukan banyak hal berguna lainnya, dan dokumentasi yang ditautkan melakukan pekerjaan yang sangat baik untuk menunjukkan hal itu.

BautKey
sumber
7

Seperti @KaptajnKold telah menjawab

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

Dan Anda tidak perlu mendefinisikan setiap parameter untuk fungsi call_me juga. Anda bisa menggunakannyaarguments

function call_me () {
    // arguments is a array consisting of params.
    // arguments[0] == 'p0',
    // arguments[1] == 'p1',
    // arguments[2] == 'p2'
}
徐 竟 峰
sumber
4
Ini adalah praktik yang buruk ... Anda tidak dapat melihat apa yang dibutuhkan fungsi dan setiap parameter opsional jika Anda melihat fungsi.
Robin
3

Catat ini

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

};

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

halaman 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>

dapat memanggil fungsi dengan Args apa saja

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

atau

<body onmousemove="FollowMouse(d1)">
ali
sumber
Ini jelas bagian dari jawabannya. "argumen" jelas diperlukan untuk mendapatkan kembali array setelah panggilan. Terima kasih!
FlorianB
2

Argumen fungsi juga bisa menjadi Array:

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

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

tentu saja orang juga dapat menggunakan spread :

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

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

vsync
sumber
2

Saat menggunakan operator spread kita harus mencatat bahwa itu harus menjadi parameter terakhir atau satu-satunya yang dilewati. Jika tidak maka akan gagal.

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

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

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

Jika Anda perlu meneruskan array sebagai argumen awal yang dapat Anda lakukan:

function callMe(arr, name){
    let newArr = [...arr];
    alert(newArr);
}
Naba
sumber
1

Anda dapat menggunakan operator spread dalam bentuk yang lebih mendasar

[].concat(...array)

dalam hal fungsi yang mengembalikan array tetapi diharapkan untuk lulus sebagai argumen

Contoh:

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

JSON.stringify(expectArguments(1,2,3)) === JSON.stringify(expectArguments([1,2,3]))
rman
sumber
0

Jawabannya sudah diberikan, tetapi saya hanya ingin memberikan sepotong kue. Apa yang ingin Anda capai disebut method borrowingdalam konteks JS, bahwa ketika kita mengambil metode dari suatu objek dan menyebutnya dalam konteks objek lain. Sangat umum untuk mengambil metode array dan menerapkannya pada argumen. Biarkan saya memberi Anda sebuah contoh.

Jadi kita memiliki fungsi hashing "super" yang mengambil dua angka sebagai argumen dan mengembalikan string hash "super safe":

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

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

Sejauh ini bagus, tapi kami punya sedikit masalah dengan pendekatan di atas, dibatasi, hanya bekerja dengan dua angka, yang tidak dinamis, mari kita membuatnya bekerja dengan angka apa pun dan ditambah Anda tidak harus melewati array (Anda bisa jika Anda masih bersikeras). Ok, cukup bicara, ayo bertarung!

Solusi alami adalah dengan menggunakan arr.joinmetode:

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

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

Oh man. Sayangnya, itu tidak akan berhasil. Karena kita memanggil hash (argumen) dan objek argumen adalah iterable dan seperti array, tetapi bukan array nyata. Bagaimana dengan pendekatan di bawah ini?

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

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

Triknya disebut method borrowing.

Kami meminjam joinmetode dari array reguler [].join.dan menggunakannya [].join.calluntuk menjalankannya dalam konteks arguments.

Mengapa ini berhasil?

Itu karena algoritma internal metode asli arr.join(glue)sangat sederhana.

Diambil dari spesifikasi hampir “apa adanya”:

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.

Jadi, secara teknis dibutuhkan ini dan bergabung dengan ini [0], ini [1] ... dll bersama. Ini sengaja ditulis dengan cara yang memungkinkan array seperti ini (bukan kebetulan, banyak metode mengikuti praktik ini). Itu sebabnya ini juga bekerja dengan baikthis=arguments.

Humoyun Ahmad
sumber