JQuery $ (this) ile ES6 Arrow Functions'ı kullanma (bu bağlama sözlü)


129

ES6 ok işlevlerini sözcüksel thisciltleme ile kullanmak harika.

Ancak, bir dakika önce tipik bir jQuery tıklama bağlamasıyla kullanarak bir sorunla karşılaştım:

class Game {
  foo() {
    self = this;
    this._pads.on('click', function() {
      if (self.go) { $(this).addClass('active'); }
    });
  }
}

Bunun yerine bir ok işlevi kullanın:

class Game {
  foo() {
    this._pads.on('click', () => {
      if (this.go) { $(this).addClass('active'); }
    });
  }
}

Ve sonra $(this)ES5 (self = this) tipi kapamaya dönüştürülür.

Traceur'ün sözcüksel bağlama için "$ (this)" i yok saymasını sağlamanın bir yolu var mı?


Bu, bir ok işlevinin ne zaman kullanılmaması gerektiğine dair mükemmel bir örnek gibi görünüyor, çünkü .on()gerçekten thissizin için yararlı bir değere sahip . Bana thisgöre olay hedefine atıfta bulunmak, olayı geçmek ve hedefi manuel olarak bulmaktan çok daha net . Ok işlevleriyle pek oynamadım ama anonim işlevlerle ileri geri gitmek kafa karıştırıcı olacak gibi görünüyor.
robisrob

Yanıtlar:


194

Bunun Traceur ve bir şeyi kapatmakla ilgisi yok, ES6 bu şekilde çalışıyor. Bunun =>yerine kullanarak istediğiniz özel işlevdir function () { }.

ES6 yazmak istiyorsanız, her zaman ES6 yazmanız gerekir, belirli kod satırlarına girip çıkamazsınız ve =>çalışma şeklini kesinlikle bastıramaz veya değiştiremezsiniz . Yapabilseniz bile, yalnızca sizin anladığınız ve kişiselleştirilmiş Traceur'unuzun dışında asla düzgün çalışmayan tuhaf bir JavaScript sürümü ile karşılaşacaksınız, ki bu kesinlikle Traceur'un amacı değildir.

Bu sorunu çözmenin yolu this, tıklanan öğeye erişim elde etmek için kullanmak değil , bunun yerine şunu kullanmaktır event.currentTarget:

Class Game {
  foo(){
    this._pads.on('click', (event) => {
      if(this.go) {
        $(event.currentTarget).addClass('active');
      }
    });
  }
}

jQuery event.currentTargetözellikle sağlar , çünkü ES6'dan önce bile jQuery'nin thisgeri arama işlevine bir ataması her zaman mümkün değildir (yani bind,.


4
Sadece delege edilen .onaramalar için farklı olmasına rağmen this, aslında olduğunu unutmayın event.currentTarget.
loganfsmyth

Bu cevap uygun mu? Loganfsmyth'in belirttiği gibi, this== event.currentTarget. Hayır?
Léon Pelletier

3
@ LéonPelletier No. thisve bir ES6 ok fonksiyonunda olduğu gibi, kapsama alanına bağlı event.currentTargetolmadıkça aynıdır this.
meagar

8
Bazı kodu kaydetmek istiyorsanız, onu ayrıca imha edebilirsiniz: ({currentTarget}) => {$ (currentTarget) .addClass ('active')}
Frank

55

Olay bağlama

$button.on('click', (e) => {
    var $this = $(e.currentTarget);
    // ... deal with $this
});

döngü

Array.prototype.forEach.call($items, (el, index, obj) => {
    var $this = $(el);
    // ... deal with $this
});

Arıyorsunuz $jQueryElements.each()? jQuery aslında her nesneye bazı argümanlar gönderir, böylece buna hiç ihtiyacınız olmaz => It's$(...).each((index, el) => console.log(el))
jave.web

53

Başka bir durum

En üstteki cevap doğru ve ben onu yükselttim.

Ancak başka bir durum daha var:

$('jquery-selector').each(() => {
    $(this).click();
})

Şu şekilde düzeltilebilir:

$('jquery-selector').each((index, element) => {
    $(element).click();
})

Bu, jQuery'deki tarihsel bir hatadır ve ilk argüman olarak öğe yerine dizini koyar :

.each (işlev)

işlev
Türü: Function( Integer index, Element element )
Her eşleşen öğe için yürütülecek işlev.

Bakınız: https://api.jquery.com/each/#each-function


1
Gibi fucntions için aynı$('jquery-selector').map
Nicholas Siegmundt

Bu, $ ['jquery-selector']. Filter vb. Gibi şeylerde kullanmak benim için çok faydalı oldu ... bu kadar net yaptığınız için teşekkürler.
R Jones

8

(Bu, bu sorunun başka bir versiyonu için yazdığım bir cevaptır, öğrenmeden önce bu sorunun bir kopyasıydı. Cevabın bilgiyi oldukça net bir şekilde bir araya getirdiğini düşünüyorum, bu yüzden büyük ölçüde farklı olmasına rağmen onu bir topluluk wiki olarak eklemeye karar verdim. diğer cevapların ifade edilmesi.)

Yapamazsın. Bu, ok işlevlerinin yarısıdır, thisnasıl adlandırıldıklarına göre belirlenen kendilerine ait olmak yerine kapatırlar. Sorudaki kullanım örneği için this, işleyiciyi çağırırken jQuery tarafından ayarlanmasını istiyorsanız , işleyicinin bir functionişlev olması gerekir .

Ancak bir ok kullanmak için bir nedeniniz varsa (belki de thisokun dışında ne anlama geldiğini kullanmak istiyorsanız ), isterseniz e.currentTargetyerine kullanabilirsiniz this:

class Game {
  foo(){
    this._pads.on('click', e => {                   // Note the `e` argument
      if(this.go) {
        $(e.currentTarget).addClass('active');      // Using it
      }
    });
  }
}

currentTargetOlay nesne üzerinde jQuery farklı kılan aynıdır thissizin işleyicisi çağrılırken için.


5

As Yetersiz aynı soru üzerine yaptığı cevaben sen ES6 yazmak istiyorsanız, ES6 her zaman yazmaya gerek ,

yani ES6'nın ok işlevini kullanıyorsanız: yerine (event)=>{}kullanmak zorundasınız .$(event.currentTarget)$(this)

Ayrıca olarak currentTarget kullanmanın daha güzel ve daha temiz şekilde kullanabilirsiniz ({currentTarget})=>{},

Class Game {
  foo(){
    this._pads.on('click', ({currentTarget}) => {
      if(this.go) {
        $(currentTarget).addClass('active');
      }
    });
  }
}

Aslında bu fikir, @ Meager'in cevabında rizzi frank tarafından yorumlanmıştı ve bunun yararlı olduğunu hissettim ve bence herkes bu yorumu okumayacak, bu yüzden bunu başka bir cevap olarak yazdım.

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.