มาดูฟังก์ชันลูกศรกันอีกครั้ง
ฟังก์ชั่นลูกศรไม่ได้เป็นเพียง “ชวเลข” สำหรับการเขียนเรื่องเล็กๆ น้อยๆ มีคุณสมบัติเฉพาะและมีประโยชน์บางประการ
JavaScript เต็มไปด้วยสถานการณ์ที่เราต้องเขียนฟังก์ชันเล็กๆ ที่ถูกเรียกใช้งานจากที่อื่น
ตัวอย่างเช่น:
arr.forEach(func)
– func
ดำเนินการโดย forEach
สำหรับทุกรายการอาร์เรย์
setTimeout(func)
– func
ดำเนินการโดยตัวกำหนดตารางเวลาในตัว
…ยังมีอีกมาก
มันเป็นจิตวิญญาณของ JavaScript ในการสร้างฟังก์ชั่นและส่งต่อมันไปที่ใดที่หนึ่ง
และในฟังก์ชันดังกล่าว เรามักจะไม่ต้องการละทิ้งบริบทปัจจุบัน นั่นคือจุดที่ฟังก์ชันลูกศรมีประโยชน์
ดังที่เราจำได้จากบท Object method ว่า "this" ฟังก์ชันลูกศรไม่มี this
หากเข้าถึง this
ก็จะนำมาจากภายนอก
ตัวอย่างเช่น เราสามารถใช้มันเพื่อวนซ้ำภายในวิธีการวัตถุ:
ให้กลุ่ม = { หัวเรื่อง: "กลุ่มของเรา", นักเรียน: ["จอห์น", "พีท", "อลิซ"], แสดงรายการ() { this.students.forEach( นักเรียน => การแจ้งเตือน (this.title + ': ' + นักเรียน) - - - กลุ่ม.showList();
ในที่นี้ forEach
จะใช้ฟังก์ชันลูกศร ดังนั้น this.title
ในนั้นจึงเหมือนกับในเมธอดภายนอก showList
ทุกประการ นั่นคือ: group.title
หากเราใช้ฟังก์ชัน "ปกติ" ก็จะมีข้อผิดพลาด:
ให้กลุ่ม = { หัวเรื่อง: "กลุ่มของเรา", นักเรียน: ["จอห์น", "พีท", "อลิซ"], แสดงรายการ() { this.students.forEach (ฟังก์ชั่น (นักเรียน) { // ข้อผิดพลาด: ไม่สามารถอ่านคุณสมบัติ 'ชื่อ' ของไม่ได้กำหนด การแจ้งเตือน (this.title + ': ' + นักเรียน); - - - กลุ่ม.showList();
ข้อผิดพลาดเกิดขึ้นเนื่องจาก forEach
รันฟังก์ชันด้วย this=undefined
ตามค่าเริ่มต้น ดังนั้นจึงมีความพยายามในการเข้าถึง undefined.title
นั่นไม่ส่งผลกระทบต่อฟังก์ชั่นลูกศรเพราะมันไม่มี this
ฟังก์ชันลูกศรไม่สามารถทำงานได้กับ new
การไม่มี this
ตามธรรมชาติหมายถึงข้อจำกัดอื่น: ฟังก์ชันลูกศรไม่สามารถใช้เป็นตัวสร้างได้ ไม่สามารถเรียก new
ได้
ฟังก์ชันลูกศร VS ผูก
มีความแตกต่างเล็กน้อยระหว่างฟังก์ชันลูกศร =>
และฟังก์ชันปกติที่เรียกด้วย .bind(this)
:
.bind(this)
สร้าง "เวอร์ชันที่ถูกผูกไว้" ของฟังก์ชัน
ลูกศร =>
ไม่ได้สร้างการเชื่อมโยงใดๆ ฟังก์ชั่นก็ไม่มี this
การค้นหา this
ทำในลักษณะเดียวกับการค้นหาตัวแปรปกติทุกประการ: ในสภาพแวดล้อมคำศัพท์ภายนอก
ฟังก์ชันลูกศรยังไม่มีตัวแปร arguments
เหมาะสำหรับนักตกแต่ง เมื่อเราต้องการโอนสายด้วย this
และ arguments
ในปัจจุบัน
ตัวอย่างเช่น defer(f, ms)
รับฟังก์ชันและส่งกลับ wrapper รอบๆ ซึ่งทำให้การโทรล่าช้าไป ms
มิลลิวินาที:
ฟังก์ชั่นเลื่อนออกไป (f, ms) { ฟังก์ชันส่งคืน () { setTimeout(() => f.apply (นี่, อาร์กิวเมนต์), ms); - - ฟังก์ชั่น sayHi (ใคร) { alert('สวัสดี' + ใคร); - ให้ sayHiDeferred = เลื่อน (sayHi, 2000); sayHiDeferred("จอห์น"); // สวัสดี จอห์น หลังจากผ่านไป 2 วินาที
สิ่งเดียวกันนี้หากไม่มีฟังก์ชันลูกศรจะมีลักษณะดังนี้:
ฟังก์ชั่นเลื่อนออกไป (f, ms) { ฟังก์ชันส่งคืน (...args) { ให้ ctx = นี่; setTimeout (ฟังก์ชัน () { กลับ f.apply (ctx, args); }, มิลลิวินาที); - -
ที่นี่เราต้องสร้างตัวแปรเพิ่มเติม args
และ ctx
เพื่อให้ฟังก์ชันภายใน setTimeout
สามารถรับพวกมันได้
ฟังก์ชั่นลูกศร:
อย่ามี this
อย่ามี arguments
ไม่สามารถเรียกกับ new
ได้
พวกเขาไม่มี super
ด้วย แต่เรายังไม่ได้ศึกษามัน เราจะพูดถึงเรื่องมรดกในบทที่
นั่นเป็นเพราะพวกเขามีไว้สำหรับโค้ดสั้นๆ ที่ไม่มี "บริบท" ของตัวเอง แต่ใช้งานได้ในปัจจุบัน และมันโดดเด่นมากในกรณีการใช้งานนั้น