Melewati fungsi dengan parameter sebagai parameter?


151

Apakah mungkin untuk melewatkan fungsi javascript dengan parameter sebagai parameter?

Contoh:

$(edit_link).click( changeViewMode( myvar ) );

5
Sepertinya JQuery, dan kemungkinan besar memang demikian, tetapi itu tidak relevan. Penggunaan atau parameter dan fungsinya sama, apa pun pustaka Javascript yang Anda gunakan.
Guffa

@ Guffa - Saya bertanya-tanya apakah itu harus ditandai dengan jQuery
Russ Cam

1
@Lucia Silakan pertimbangkan untuk mengubah jawaban yang diterima untuk ini .
Michał Perłakowski

Jika Anda bekerja dengan React, pertimbangkan stackoverflow.com/questions/41369497/…
Michael Freidgeim

Jawaban:


244

Gunakan "penutupan":

$(edit_link).click(function(){ return changeViewMode(myvar); });

Ini menciptakan pembungkus fungsi sementara anonim yang tahu tentang parameter dan meneruskannya ke implementasi panggilan balik yang sebenarnya.


3
Jika Anda ingin memanggil suatu fungsi pada suatu objek, Anda perlu memanggil bind (). myObj.click (function () {this.doSomething ();} .bind (myObj)); Itu akan membuat "ini" menjadi myObj.
Eli

1
Bukankah ini masalah kinerja ketika berurusan dengan banyak dari ini? Misalnya, Anda membuat onPress dalam satu Baris dan Anda memiliki 10.000 baris. Ini membuat pembungkus fungsi sementara anonim baru untuk setiap Baris. Apakah ada cara lain untuk melakukannya?
Joshua Pinter

@ JoshuaPinter Teknik itu sendiri tidak menjadi masalah. Jika Anda membutuhkan panggilan fungsi yang sama 10.000 kali, Anda dapat menyimpan pembungkusnya dalam sebuah variabel, sehingga Anda membuatnya hanya sekali. Jika Anda harus melewati 10.000 konteks yang berbeda, ada sedikit yang bisa Anda lakukan. Waspadai pengoptimalan prematur: Seperti biasa dengan kinerja, Anda perlu mengukur untuk melihat apakah ada masalah atau tidak. Mesin JavaScript saat ini sangat kuat dan dapat mengoptimalkan kode dengan cara yang mengejutkan.
Ferdinand Beyer

@FerdinandBeyer Luar Biasa, terima kasih atas tipnya. Seorang teman memberi tahu saya bahwa itu adalah praktik yang buruk dan Anda sebaiknya menggunakan metode this.myFunction = this.myFunction.bind(this)Anda constructor. Tetapi, seperti yang Anda katakan, ketika Anda harus memberikan konteks berbeda untuk masing-masing, seperti semua baris yang Anda klik untuk membuka halaman detail baris itu, itu tidak dapat dihindari.
Joshua Pinter

@FerdinandBeyer, katakanlah myvar adalah string dan itu berubah antara dua doa berturut-turut melewati changeViewMode sebagai penutup, tetapi changeViewMode selalu menerima nilai pertama dari myvar, saya ingin memanggil fungsi penutupan dengan nilai argumen berbeda yang ditugaskan ke variabel myvar yang sama,
nmxprime

42

Gunakan Function.prototype.bind(). Mengutip MDN:

The bind()Metode menciptakan fungsi baru yang, saat dipanggil, memiliki nya thisset kata kunci untuk nilai disediakan, dengan urutan tertentu argumen sebelumnya yang disediakan ketika fungsi baru ini disebut.

Ini didukung oleh semua browser utama, termasuk IE9 +.

Kode Anda akan terlihat seperti ini:

$(edit_link).click(changeViewMode.bind(null, myvar));

Catatan: Saya menganggap Anda berada dalam konteks global, yaitu thisvariabelnya adalah window; jika tidak gunakan thissebagai ganti null.


Terima kasih, ini membantu saya. Digunakan seperti ini:$.ajax(url).done(handler.bind(this, var1, var2));
Thomas

2
Opsi mana yang terbaik? Menggunakan penutupan atau menggunakan fungsi bind? Tolong beri tahu saya jika ada dampak kinerja
Varun


15

Tidak, tetapi Anda dapat melewatkannya tanpa parameter, dan lakukan ini:

$(edit_link).click(
  function() { changeViewMode(myvar); }
);

Jadi Anda melewati fungsi anonim tanpa parameter, fungsi itu lalu memanggil fungsi parameter Anda dengan variabel dalam penutupan



7

Atau jika Anda menggunakan es6, Anda harus dapat menggunakan fungsi panah

$(edit_link).click(() => changeViewMode(myvar));

2

Kamu bisa melakukan ini

var message  = 'Hello World';

var callback = function(){
alert(this)
}.bind(message);

lalu

function activate(callback){
  callback && callback();
}

activate(callback);

Atau jika panggilan balik Anda mengandung logika yang lebih fleksibel, Anda dapat melewati objek.

Demo


2

Ini adalah contoh mengikuti pendekatan Ferdinand Beyer:

function function1()
{
    function2(function () { function3("parameter value"); });
}
function function2(functionToBindOnClick)
{
    $(".myButton").click(functionToBindOnClick);
}
function function3(message) { alert(message); }

Dalam contoh ini "nilai parameter" dilewatkan dari function1 ke function3 melalui function2 menggunakan pembungkus fungsi.

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.