Soru Bağlamı anonim işleve nasıl geçiririm?


Bazı işlevler vardır, uzun bir iş yapar ve geri çağırma sağlar.

someFunc: function(argument, callback, context) {
  // do something long

  // call callback function
  callback(context);
}

Uygulamada bu işlevi kullanıyorum

someFunc('bla-bla', function (context) {
  // do something with this scope
  context.anotherFunc();
}, this);

Geri çağırma işlevi nasıl geçmeden uygulanır? context parametre?

Bunun gibi bazı ihtiyaç var:

someFunc('bla-bla', function () {
  // do something with this scope
  this.anotherFunc();
}, this);

25
2017-11-08 01:49


Menşei


Yani, son örneğinizde, bağlamı geçtiğiniz (en azından bir şeye) görünüyorsanız, eğer adlandırılmışsa argümana nasıl başvurulacağını merak ediyor musunuz? - Quintin Robinson
Parametreyi geçiyorsunuz, onu kullanmıyorsunuz. Ve nedenini anlamıyorum. - bfavaretto
@bfavaretto: OP, geri çağırma yöntemine geçerek onu kullanıyor, böylece geri arama, dış yöntemlerden yararlanabiliyor this değer. Öyleyse soru, son kod bloğunun nasıl elde edileceğidir. this geri aramada argüman olarak geçilmesine gerek yoktur. - I Hate Lazy


Cevaplar:


Kabul edilen cevap biraz modası geçmiş gibi görünüyor. Göreceli olarak modern bir tarayıcıda çalıştığınızı varsayarak kullanabilirsiniz Function.prototype.bind içinde vanilla javascript. Alternatif olarak, eğer kullanıyorsanız vurgulamak veya jQuery, kullanabilirsiniz _.bind veya $.proxy sırasıyla call/apply Eğer gerekliyse).

İşte bu üç seçenekten oluşan basit bir gösteri:

// simple function that takes another function
// as its parameter and then executes it.
function execute_param(func) {
    func();
}

// dummy object. providing an alternative context.
obj = {};
obj.data = 10;

// no context provided
// outputs 'Window'
execute_param(function(){
    console.log(this);
});

// context provided by js - Function.prototype.bind
// src: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
// outputs 'Object { data=10 }''
execute_param(function(){
    console.log(this);
}.bind(obj));

// context provided by underscore - _.bind
// src: http://underscorejs.org/#bind
// outputs 'Object { data=10 }'
execute_param(_.bind(function(){
    console.log(this);
},obj));

// context provided by jQuery - $.proxy
// src: http://api.jquery.com/jQuery.proxy/
// outputs 'Object { data=10 }'
execute_param($.proxy(function(){
    console.log(this);
},obj));

Kodu burada bir jsfiddle'da bulabilirsiniz: http://jsfiddle.net/yMm6t/1/ (not: geliştirici konsolunun açık olduğundan emin olun, yoksa herhangi bir çıktı görmezsiniz)


39
2017-10-20 01:26



Evet. Şimdi her yerde alt çizgi kullanıyorum :) - acelot
@PiONeeR Evet, bende :) Kabul edilen cevap ne olmalı diye yeniden düşünmek isteyebilirsiniz. - EleventyOne
Bu kabul edilen cevap olmalı. - Gamak
Nasıl bağlanır this Başka bir değişken adı altında? Sevmek .bind(that)? - Jonathan


kullanım Function.prototype.call Bir işlevi çağırmak ve manuel olarak this Bu fonksiyonun değeri.

someFunc: function(argument, callback, context) {
    callback.call(context); // call the callback and manually set the 'this'
}

Şimdi geri dönüşünüz beklenen this değer.

someFunc('bla-bla', function () {
  // now 'this' is what you'd expect
    this.anotherFunc();
}, this);

Tabi ki normalde argümanlar gibi .call çağırma.

callback.call(context, argument);

13
2017-11-08 01:53