การใช้ jQuery $ (this) กับ ES6 Arrow Functions (คำศัพท์การผูกนี้)


129

การใช้ฟังก์ชันลูกศร ES6 กับการthisผูกศัพท์นั้นยอดเยี่ยมมาก

อย่างไรก็ตามฉันพบปัญหาเมื่อสักครู่ที่ผ่านมาโดยใช้กับการเชื่อมโยงการคลิก jQuery ทั่วไป:

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

ใช้ฟังก์ชันลูกศรแทน:

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

จากนั้น$(this)จะถูกแปลงเป็น ES5 (self = this) type closed

เป็นวิธีที่จะให้ Traceur ละเว้น "$ (this)" สำหรับการผูกศัพท์หรือไม่?


นี้ดูเหมือนว่าเป็นตัวอย่างที่สมบูรณ์แบบของเมื่อไม่ได้ใช้งานฟังก์ชั่นลูกศรตั้งแต่.on()ไม่แน่นอนมีthisค่าเป็นประโยชน์กับคุณ สำหรับฉันแล้วการthisอ้างถึงเป้าหมายเหตุการณ์นั้นชัดเจนกว่าการต้องส่งผ่านเหตุการณ์และค้นหาเป้าหมายด้วยตนเอง ฉันไม่ค่อยได้เล่นกับฟังก์ชั่นลูกศรมากนัก แต่ดูเหมือนว่ามันจะสับสนเมื่อต้องกลับไปกลับมากับฟังก์ชันนิรนาม
robisrob

คำตอบ:


194

สิ่งนี้ไม่มีส่วนเกี่ยวข้องกับ Traceur และการปิดบางอย่างนี่เป็นเพียงวิธีการทำงานของ ES6 มันเป็นฟังก์ชั่นที่เฉพาะเจาะจงที่คุณขอโดยใช้แทน=>function () { }

หากคุณต้องการเขียน ES6 คุณต้องเขียน ES6 ตลอดเวลาคุณไม่สามารถสลับเข้าและออกจากโค้ดบางบรรทัดได้และคุณไม่สามารถระงับหรือเปลี่ยนแปลงวิธีการ=>ทำงานได้อย่างแน่นอน แม้ว่าคุณจะทำได้ แต่คุณก็จะจบลงด้วย JavaScript เวอร์ชันแปลกประหลาดที่มีเพียงคุณเท่านั้นที่เข้าใจและจะไม่มีวันทำงานได้อย่างถูกต้องนอกเหนือจาก Traceur ที่คุณกำหนดเองซึ่งแน่นอนว่าไม่ใช่ประเด็นของ Traceur

วิธีแก้ปัญหาเฉพาะนี้ไม่ได้ใช้thisเพื่อเข้าถึงองค์ประกอบที่คลิก แต่ให้ใช้event.currentTarget:

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

jQuery จัดเตรียมไว้เป็นevent.currentTargetพิเศษเนื่องจากแม้กระทั่งก่อน ES6 เป็นไปไม่ได้เสมอไปที่ jQuery จะกำหนดthisฟังก์ชันการเรียกกลับ (กล่าวคือหากถูกผูกไว้กับบริบทอื่นผ่านbindไฟล์.


4
หมายเหตุแม้ว่ามันเพียง diverges สำหรับมอบหมาย.onสายเป็นจริงthis event.currentTarget
loganfsmyth

คำตอบนี้โอเคไหม เช่นเดียวกับ loganfsmyth สังเกต==this event.currentTargetไม่มี?
Léon Pelletier

3
@ LéonPelletier No. thisและevent.currentTargetจะเหมือนกันเว้นแต่thisจะถูกผูกไว้กับขอบเขตการปิดล้อมเช่นเดียวกับฟังก์ชันลูกศร ES6
meagar

8
หากคุณต้องการบันทึกโค้ดคุณสามารถทำลายโครงสร้างได้ด้วย: ({currentTarget}) => {$ (currentTarget) .addClass ('active')}
Frank

55

การผูกเหตุการณ์

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

ห่วง

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

กำลังมองหา$jQueryElements.each()? jQuery ส่งอาร์กิวเมนต์ไปยังแต่ละวัตถุดังนั้นคุณจึงไม่ต้องการสิ่งนี้เลย => มัน$(...).each((index, el) => console.log(el))
jave.web

53

อีกกรณีหนึ่ง

คำตอบด้านบนถูกต้องและฉันได้รับการโหวตแล้ว

อย่างไรก็ตามมีอีกกรณีหนึ่ง:

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

สามารถแก้ไขได้เป็น:

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

นี่เป็นข้อผิดพลาดทางประวัติศาสตร์ใน jQuery ซึ่งทำให้ดัชนีแทนที่จะเป็นองค์ประกอบเป็นอาร์กิวเมนต์แรก:

.each (ฟังก์ชัน)


ประเภทฟังก์ชัน : Function( Integer index, Element element )
ฟังก์ชันที่จะดำเนินการสำหรับแต่ละองค์ประกอบที่ตรงกัน

ดู: https://api.jquery.com/each/#each-function


1
เหมือนกันสำหรับ fucntions เช่น$('jquery-selector').map
Nicholas Siegmundt

สิ่งนี้มีประโยชน์มากสำหรับฉันที่จะใช้ในสิ่งต่างๆเช่น $ ('jquery-selector') ตัวกรอง ฯลฯ ... ขอบคุณที่ทำให้ชัดเจน
R Jones

8

(นี่เป็นคำตอบที่ฉันเขียนสำหรับคำถามรุ่นอื่นก่อนที่จะเรียนรู้ว่าคำถามนี้ซ้ำกันฉันคิดว่าคำตอบนั้นดึงข้อมูลมารวมกันค่อนข้างชัดเจนดังนั้นฉันจึงตัดสินใจเพิ่มเป็นวิกิชุมชนแม้ว่าจะแตกต่างกันมากก็ตาม วลีของคำตอบอื่น ๆ )

คุณทำไม่ได้ นั่นคือครึ่งหนึ่งของฟังก์ชั่นลูกศรมันปิดthisแทนที่จะมีของตัวเองซึ่งกำหนดโดยวิธีการเรียก สำหรับกรณีการใช้งานในคำถามหากคุณต้องการthisตั้งค่าโดย jQuery เมื่อเรียกตัวจัดการตัวจัดการจะต้องเป็นfunctionฟังก์ชัน

แต่ถ้าคุณมีเหตุผลในการใช้ลูกศร (บางทีคุณอาจต้องการใช้thisเพื่อความหมายนอกลูกศร) คุณสามารถใช้e.currentTargetแทนได้thisหากต้องการ:

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

currentTargetบนวัตถุเหตุการณ์เป็นเช่นเดียวกับสิ่งที่ jQuery ชุดthisไปเมื่อโทรจัดการของคุณ


5

ในฐานะที่เป็นผอมกล่าวว่าในคำตอบของเขาในคำถามเดียวกันนี้หากคุณต้องการที่จะเขียน ES6 คุณต้องเขียน ES6 ตลอดเวลา ,

ดังนั้นหากคุณใช้ฟังก์ชันลูกศรของ ES6: (event)=>{}คุณต้องใช้$(event.currentTarget)แทน$(this).

คุณยังสามารถใช้วิธีการทำความสะอาดมากขึ้นและดีกว่าของการใช้ currentTarget เป็น ({currentTarget})=>{},

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

แต่เดิมความคิดนี้ถูกแสดงความคิดเห็นโดยrizzi frankในคำตอบของ @ Meager และฉันรู้สึกว่ามันมีประโยชน์และฉันคิดว่าไม่ใช่ทุกคนที่จะอ่านความคิดเห็นนั้นดังนั้นฉันจึงเขียนมันเป็นคำตอบอื่น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.