⊗jsPmTrTCL 451 of 505 menu

ไทเมอร์และการสูญเสียคอนเท็กซ์ใน JavaScript

เมื่อใช้ไทเมอร์ในอีเวนต์แฮนด์เลอร์ เรามักจะพบปัญหาการสูญเสียคอนเท็กซ์ ลองดูตัวอย่างกัน

สมมติว่าเรามีอินพุต:

<input id="elem" value="text">

สมมติว่าเมื่อคลิกที่อินพุตนี้ ฟังก์ชันนิรนาม จะทำงาน และภายในฟังก์ชันนั้นจะมีไทเมอร์ ที่ทำงานทุกวินาทีเพื่อแสดงผลบางอย่าง ในคอนโซล:

let elem = document.querySelector('#elem'); elem.addEventListener('click', function() { setInterval(function() { console.log('!!!'); // แสดงผลบางอย่างในคอนโซล }, 1000); });

ทุกอย่างทำงานได้ถูกต้อง แต่ตอนนี้สมมติว่า เราต้องการแสดงผลค่า value ของอินพุตของเราในคอนโซล - เราจะต้องประหลาดใจ: ในคอนโซล จะแสดงผลเป็น undefined:

elem.addEventListener('click', function() { setInterval(function() { console.log(this.value); // จะแสดงผลเป็น undefined }, 1000); });

ทั้งหมดนี้เป็นเพราะเรามีฟังก์ชัน ภายในฟังก์ชัน: มีฟังก์ชันนิรนามภายนอก ที่ถูกเรียกเมื่อคลิก และฟังก์ชันนิรนามภายใน ที่ถูกเรียกโดยไทเมอร์ ในฟังก์ชันภายนอก this ชี้ไปที่ อินพุต แต่ในฟังก์ชันภายใน - ไม่ นี่คือกรณีของ การสูญเสียคอนเท็กซ์

ทำไมจึงแสดงผล undefined และไม่เกิด ข้อผิดพลาดในคอนโซล อย่างที่เคยเป็นในบทเรียนก่อนๆ? เพราะว่า this ภายในฟังก์ชัน ที่ถูกเรียกผ่าน setInterval ชี้ไปที่ window

นี่หมายความว่าเราพยายามอ่านคุณสมบัติ value จากออบเจ็กต์ window แบบนี้: window.value แต่คุณสมบัตินั้นไม่มีอยู่ในนั้น และเราได้ undefined (ไม่ใช่ข้อผิดพลาด)

มาแก้ไขปัญหาด้วยการนำเข้า self:

elem.addEventListener('click', function() { let self = this; setInterval(function() { console.log(self.value); }, 1000); });

สมมติว่าโค้ดนี้ถูกกำหนด:

<input type="button" id="elem" value="1"> let elem = document.querySelector('#elem'); elem.addEventListener('click', function() { setInterval(function() { this.value = Number(elem.value) + 1; }, 1000); });

ผู้เขียนโค้ดต้องการให้เมื่อกดปุ่ม ค่าของปุ่มนี้จะเพิ่มขึ้นทุกวินาที ทีละ 1 อย่างไรก็ตาม เมื่อกดปุ่ม แล้วไม่มีอะไรเกิดขึ้นเลย แก้ไขข้อผิดพลาด ของผู้เขียนโค้ด เขียนข้อความที่คุณ จะให้คำอธิบายแก่ผู้เขียนโค้ดว่าทำไมจึงเกิด ข้อผิดพลาดของเขาขึ้น

ไทย
AfrikaansAzərbaycanБългарскиবাংলাБеларускаяČeštinaDanskDeutschΕλληνικάEnglishEspañolEestiSuomiFrançaisहिन्दीMagyarՀայերենIndonesiaItaliano日本語ქართულიҚазақ한국어КыргызчаLietuviųLatviešuМакедонскиMelayuမြန်မာNederlandsNorskPolskiPortuguêsRomânăРусскийසිංහලSlovenčinaSlovenščinaShqipСрпскиSrpskiSvenskaKiswahiliТоҷикӣTürkmenTürkçeЎзбекOʻzbekTiếng Việt
เราใช้คุกกี้สำหรับการทำงานของเว็บไซต์ การวิเคราะห์ และการปรับเนื้อหาให้เหมาะสมส่วนบุคคล การประมวลผลข้อมูลเกิดขึ้นตาม นโยบายความเป็นส่วนตัว.
ยอมรับทั้งหมด ปรับแต่ง ปฏิเสธ