tl; dr: ไม่! ฟังก์ชั่นลูกศรและการประกาศฟังก์ชั่น / การแสดงออกไม่เทียบเท่าและไม่สามารถแทนที่สุ่มสี่สุ่มห้าได้
หากฟังก์ชั่นที่คุณต้องการที่จะเปลี่ยนไม่ได้ใช้this
, arguments
และไม่ได้เรียกว่ามีnew
แล้วใช่
จึงมักจะเป็น: มันขึ้นอยู่กับ ฟังก์ชั่นลูกศรมีพฤติกรรมที่แตกต่างจากฟังก์ชั่นการประกาศ / การแสดงออกดังนั้นเรามาดูความแตกต่างก่อน:
1. คำศัพท์this
และarguments
ฟังก์ชั่นลูกศรไม่มีของตัวเองthis
หรือarguments
มีผลผูกพัน แต่ตัวระบุเหล่านั้นจะได้รับการแก้ไขในขอบเขตศัพท์เช่นตัวแปรอื่น ๆ ซึ่งหมายความว่าภายในฟังก์ชั่นลูกศรthis
และarguments
อ้างถึงค่าของthis
และarguments
ในสภาพแวดล้อมฟังก์ชั่นลูกศรถูกกำหนดใน (เช่น "นอก" ฟังก์ชั่นลูกศร):
// Example using a function expression
function createObject() {
console.log('Inside `createObject`:', this.foo);
return {
foo: 42,
bar: function() {
console.log('Inside `bar`:', this.foo);
},
};
}
createObject.call({foo: 21}).bar(); // override `this` inside createObject
// Example using a arrow function
function createObject() {
console.log('Inside `createObject`:', this.foo);
return {
foo: 42,
bar: () => console.log('Inside `bar`:', this.foo),
};
}
createObject.call({foo: 21}).bar(); // override `this` inside createObject
ในกรณีที่การแสดงออกของฟังก์ชั่นที่หมายถึงวัตถุที่ถูกสร้างขึ้นภายในthis
createObject
ฟังก์ชั่นในกรณีที่ลูกศรthis
หมายถึงthis
ของcreateObject
ตัวเอง
สิ่งนี้ทำให้ฟังก์ชั่นลูกศรมีประโยชน์หากคุณต้องการเข้าถึงthis
สภาพแวดล้อมปัจจุบัน:
// currently common pattern
var that = this;
getData(function(data) {
that.data = data;
});
// better alternative with arrow functions
getData(data => {
this.data = data;
});
หมายเหตุว่าเรื่องนี้ก็หมายความว่าเป็นไม่ได้ที่เป็นไปได้ในการตั้งค่าฟังก์ชั่นของลูกศรthis
ด้วยหรือ.bind
.call
หากคุณไม่คุ้นเคยthis
ให้ลองอ่าน
2. ฟังก์ชั่นลูกศรไม่สามารถเรียกได้ด้วย new
ES2015 แยกความแตกต่างระหว่างฟังก์ชั่นที่สามารถโทรออกและฟังก์ชั่นที่สามารถสร้างได้ ถ้าทำงานเป็น constructable ก็สามารถที่จะเรียกว่ามี คือnew
new User()
หากฟังก์ชั่นสามารถเรียกใช้ได้ก็สามารถเรียกได้โดยไม่ต้องnew
(เช่นการเรียกใช้ฟังก์ชั่นปกติ)
ฟังก์ชั่นที่สร้างขึ้นผ่านการประกาศฟังก์ชั่น / การแสดงออกมีทั้งที่สามารถสร้างได้และ callable
ฟังก์ชั่นลูกศร (และวิธีการ) สามารถเรียกใช้ได้เท่านั้น
class
ตัวสร้างสามารถสร้างได้เท่านั้น
หากคุณพยายามเรียกใช้ฟังก์ชันที่ไม่สามารถเรียกได้หรือสร้างฟังก์ชันที่ไม่สามารถแก้ไขได้คุณจะได้รับข้อผิดพลาดรันไทม์
เมื่อทราบสิ่งนี้เราสามารถระบุสิ่งต่อไปนี้
ถอดเปลี่ยนได้:
- ฟังก์ชั่นที่ไม่ได้ใช้หรือ
this
arguments
- ฟังก์ชั่นที่ใช้กับ
.bind(this)
ไม่สามารถเปลี่ยนได้:
- ฟังก์ชันตัวสร้าง
- ฟังก์ชั่น / วิธีการเพิ่มต้นแบบ (เพราะพวกเขามักจะใช้
this
)
- ฟังก์ชัน Variadic (ถ้าใช้
arguments
(ดูด้านล่าง))
มาดูตัวอย่างนี้โดยละเอียด:
ฟังก์ชันตัวสร้าง
new
นี้จะไม่ทำงานเพราะฟังก์ชั่นลูกศรไม่สามารถเรียกว่ามี ใช้ฟังก์ชั่นการประกาศ / แสดงออกหรือใช้class
ต่อไป
วิธีการต้นแบบ
ไม่น่าเป็นไปได้เพราะวิธีการต้นแบบมักจะใช้this
ในการเข้าถึงอินสแตนซ์ หากไม่ได้ใช้งานthis
คุณสามารถแทนที่ได้ อย่างไรก็ตามถ้าคุณสนใจไวยากรณ์ที่รัดกุมให้ใช้class
กับไวยากรณ์ของเมธอดรัดกุม:
class User {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
วิธีการวัตถุ
ในทำนองเดียวกันสำหรับวิธีการในวัตถุตามตัวอักษร หากวิธีการที่ต้องการอ้างอิงวัตถุตัวเองผ่านthis
ให้ใช้การแสดงออกของฟังก์ชั่นหรือใช้ไวยากรณ์วิธีการใหม่:
const obj = {
getName() {
// ...
},
};
เรียกกลับ
มันขึ้นอยู่กับ. คุณควรแทนที่ถ้าคุณใช้นามแฝงด้านนอกthis
หรือกำลังใช้งาน.bind(this)
:
// old
setTimeout(function() {
// ...
}.bind(this), 500);
// new
setTimeout(() => {
// ...
}, 500);
แต่:หากโค้ดที่เรียก callback ตั้งค่าไว้อย่างชัดเจนthis
เช่นเดียวกับตัวจัดการเหตุการณ์โดยเฉพาะกับ jQuery และ callback ใช้this
(หรือarguments
) คุณจะไม่สามารถใช้ฟังก์ชันลูกศรได้!
ฟังก์ชัน Variadic
เนื่องจากฟังก์ชั่นลูกศรไม่มีของตัวเองarguments
คุณจึงไม่สามารถแทนที่ด้วยฟังก์ชั่นลูกศรได้ อย่างไรก็ตาม ES2015 แนะนำทางเลือกในการใช้arguments
คือพารามิเตอร์ที่เหลือ
// old
function sum() {
let args = [].slice.call(arguments);
// ...
}
// new
const sum = (...args) => {
// ...
};
คำถามที่เกี่ยวข้อง:
แหล่งข้อมูลเพิ่มเติม: