Parametreli bir işlevi parametre olarak mı geçiriyorsunuz?


156

Parametreli bir javascript işlevini parametre olarak geçirmek mümkün müdür?

Misal:

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

5
JQuery'ye benziyor ve büyük olasılıkla öyle, ama bu alakasız. Kullanım veya parametreler ve işlevler, kullandığınız Javascript kitaplıklarından bağımsız olarak aynıdır.
Guffa

@Guffa - jQuery ile etiketlenmesi gerekip gerekmediğini merak ediyordum
Russ Cam

1
@Lucia için kabul edilen cevabını değiştirmeyi düşünün lütfen bu .
Michał Perłakowski

Yanıtlar:


250

Bir "kapanış" kullanın:

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

Bu, parametre hakkında bilgi sahibi olan ve onu gerçek geri arama uygulamasına ileten anonim bir geçici işlev sarmalayıcısı oluşturur.


3
Bir nesnede bir işlevi çağırmak istiyorsanız, bind () öğesini çağırmanız gerekir. myObj.click (function () {this.doSomething ();} .bind (myObj)); Bu, "bu" u myObj yapar.
Eli

1
Bunların çoğuyla uğraşırken bu bir performans sorunu olmaz mı? Örneğin, bir Satırda bir onPress oluşturuyorsunuz ve 10.000 satırınız var. Bu, her Satır için yeni bir anonim geçici işlev sarmalayıcısı oluşturur. Bunu yapmanın başka bir yolu var mı?
Joshua Pinter

@JoshuaPinter Tekniğin kendisi bir sorun değil. Aynı işlevi 10.000 kez aramanız gerekiyorsa, sarmalayıcıyı bir değişkene kaydedebilir, böylece onu yalnızca bir kez oluşturursunuz. 10.000 farklı bağlamı geçmeniz gerekiyorsa, yapabileceğiniz çok az şey var. Erken optimizasyona dikkat edin: Performansta her zaman olduğu gibi , bir sorun olup olmadığını görmek için ölçmeniz gerekir . Bugünün JavaScript motorları çok güçlüdür ve kodu şaşırtıcı şekillerde optimize edebilir.
Ferdinand Beyer

@ FerdinandBeyer Harika, bahşiş için teşekkürler. Bir arkadaşım bunun kötü bir uygulama olduğunu ve bunun yerine this.myFunction = this.myFunction.bind(this)kendi constructoryönteminizde kullanmanız gerektiğini söyledi . Ancak, söylediğiniz gibi, her biri için farklı bağlamlar iletmeniz gerektiğinde, o satırın ayrıntı sayfasını açmak için tıkladığınız tüm farklı satırlar gibi, bu önlenemez.
Joshua Pinter

@FerdinandBeyer, myvar'ın bir dizge olduğunu ve bir kapanış olarak changeViewMode'u geçmenin iki ardışık çağrısı arasında değiştiğini söyleyelim, ancak changeViewMode her zaman myvar'ın ilk değerini alıyor, aynı myvar değişkenine atanmış farklı argüman değeriyle kapatma işlevini çağırmak istiyorum,
nmxprime

44

Kullanın Function.prototype.bind(). MDN'den alıntı yapmak:

bind()Yöntem çağrıldığında, onun sahip yeni bir işlev oluşturur thisyeni işlev çağrıldığında bir mesafede önceki argümanlar, belirli bir sekans ile, verilen değere kelime seti.

IE9 + dahil tüm büyük tarayıcılar tarafından desteklenir.

Kodunuz şöyle görünmelidir:

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

Yan not: Küresel bağlamda olduğunuzu varsayıyorum, yani thisdeğişken window; aksi takdirde thisyerine kullanın null.


Teşekkürler, bu bana yardımcı oldu. Bunu şu şekilde kullandım:$.ajax(url).done(handler.bind(this, var1, var2));
Thomas

2
Hangi seçenek en iyisidir? Kapatma mı yoksa bağlama işlevini mi kullanıyorsunuz? Herhangi bir performans etkisi varsa lütfen bana bildirin
Varun


16

Hayır, ancak birini parametresiz geçirebilir ve bunu yapabilirsiniz:

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

Yani, parametresiz anonim bir işlevi iletiyorsunuz, bu işlev daha sonra kapamadaki değişkenle parametreli işlevinizi çağırır.



8

Veya es6 kullanıyorsanız bir ok işlevini kullanabilmelisiniz

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

2

Bunu yapabilirsiniz

var message  = 'Hello World';

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

ve sonra

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

activate(callback);

Ya da geri aramanız daha esnek bir mantık içeriyorsa, nesneyi iletebilirsiniz.

Demo


2

Bu, Ferdinand Beyer'in yaklaşımını takip eden bir örnektir:

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

Bu örnekte "parametre değeri", bir işlev sarma kullanılarak işlev1'den işlev3'e işlev2'ye aktarılır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.