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()?

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

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])
  }
}

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


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'
}

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

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)


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

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

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.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.