Hàm mũi tên so với Hàm thông thường trong JavaScript

Giống như hầu hết mọi ngôn ngữ lập trình hiện đại, JavaScript cung cấp các cách để tạo các chức năng cho phép sử dụng lại mã. Đối với những người không quen với ngôn ngữ này, có hai cách khác nhau để khai báo một hàm trong JavaScript.
Ban đầu, các chức năng từ khóa đã được sử dụng và sau đó, cú pháp mũi tên đã được tạo. Mặc dù khác nhau về khả năng truy cập phạm vi, cả từ khóa chức năng và cú pháp mũi tên đều tạo ra kết quả tương tự.
Việc không thể phân biệt giữa hai điều này có thể gây ra sự cố và dẫn đến việc sử dụng không chính xác. Điều cần thiết đối với nhà phát triển JS hiện đại là hiểu cách mỗi khai báo hàm ảnh hưởng đến phạm vi và khả năng hiển thị.
Mục Lục
Hàm mũi tên của JavaScript là gì?
Các hàm mũi tên của JavaScript là một cách khác để xác định các hàm không sử dụng mặc định chức năng từ khóa:
function logMessage(message) {
console.log(message);
}const logMessage = (message) => {
console.log(message);
}
const logMessage = message => console.log(message);
Ở trên, bạn có thể thấy cùng một thông điệp được viết theo ba cách khác nhau. Cái đầu tiên sử dụng phương thức khai báo hàm thông thường. Hai phần tiếp theo chỉ ra hai cách để sử dụng các chức năng mũi tên của ES6.
JavaScript lần đầu tiên áp dụng cú pháp hàm mũi tên với việc phát hành các tiêu chuẩn ECMAScript 2015. Các hàm mũi tên cung cấp một cách rõ ràng và súc tích để nhanh chóng tạo các hàm và một giải pháp thú vị cho một số vấn đề về phạm vi hoạt động lâu dài trong JavaScript.
Các tính năng này nhanh chóng làm cho các chức năng mũi tên trở thành điểm nhấn của nhiều nhà phát triển. Các lập trình viên đang tìm kiếm cơ sở mã JavaScript hiện đại cũng có khả năng tìm thấy các hàm mũi tên giống như các hàm thông thường.
Các hàm mũi tên khác với các hàm thông thường trong JavaScript như thế nào?
Thoạt nhìn, các hàm mũi tên dường như không khác nhiều so với các hàm được khai báo bằng từ khóa hàm. Ngoài cú pháp, cả hai gói gọn một tập hợp các hành động có thể tái sử dụng có thể được gọi từ nơi khác trong mã.
Mặc dù có những điểm tương đồng giữa hai loại, tuy nhiên, có một số khác biệt mà các nhà phát triển cần lưu ý.
Sự khác biệt trong phạm vi
Bất cứ khi nào một hàm thông thường được khai báo trong JavaScript, thì hàm đó hoạt động như một bao đóng tạo ra phạm vi riêng của nó. Điều này có thể gây ra sự cố khi sử dụng một số chức năng chuyên biệt như setTimeout Và setInterval.
Trước ES6, đã có một số lượng đáng kể các giải pháp thay thế sẽ nâng các mục lên các mức phạm vi cao hơn để sử dụng trong các cuộc gọi lại. Những thủ thuật này đã hoạt động, nhưng chúng thường khó hiểu và có thể gây ra sự cố khi một số biến nhất định bị ghi đè.
Các chức năng mũi tên đã giải quyết cả hai vấn đề một cách đơn giản và thanh lịch. Khi một chức năng mũi tên được sử dụng như một phần của cuộc gọi lại, nó có quyền truy cập vào cùng phạm vi với chức năng mà nó được gọi.
Điều này cho phép các chức năng được sử dụng làm lệnh gọi lại mà không làm mất quyền truy cập vào ngữ cảnh mà sự kiện ban đầu được gọi. Là một thử nghiệm đơn giản để thể hiện nguyên tắc này trong thực tế, bạn có thể thiết lập chức năng gửi tin nhắn bị trì hoãn như chức năng bên dưới:
function delayedMessage(message, delay) {
setTimeout(function(message) {
console.log(message);
}, delay);}
delayedMessage("Hello World", 1000);
Chức năng đơn giản, chấp nhận tin nhắn Và trì hoãn tính bằng mili giây. Sau khi vượt qua độ trễ, nó sẽ ghi thông báo vào bảng điều khiển. Tuy nhiên, khi mã được thực thi, không xác định sẽ được ghi vào bảng điều khiển thay vì thông báo đã được chuyển vào.
Khi chức năng gọi lại được thực thi, phạm vi sẽ thay đổi và thông báo ban đầu không còn truy cập được nữa. Việc sử dụng thông báo từ bên trong bao đóng yêu cầu thông báo phải được nâng lên một biến toàn cục, điều này có thể dẫn đến việc thông báo bị ghi đè trước khi gọi lại.
Một chức năng mũi tên là một sửa chữa thích hợp cho vấn đề này. Nếu bạn thay thế đối số đầu tiên cho setTimeoutphạm vi có thể được duy trì và chức năng sẽ có quyền truy cập vào thông báo được chuyển đến tin nhắn bị trì hoãn.
function delayedMessage(message, delay) {
setTimeout(() => {
console.log(message);
}, delay);}
delayedMessage("Hello World", 1000);
Bây giờ, khi được thực thi, tin nhắn bị trì hoãn chức năng sẽ ghi lại tin nhắn. Ngoài ra, điều này cho phép nhiều tin nhắn được xếp hàng đợi với độ trễ khác nhau và tất cả chúng sẽ vẫn diễn ra vào đúng thời điểm.
Điều này là do thực tế là mỗi lần tin nhắn bị trì hoãn được sử dụng, nó tạo phạm vi riêng với bản sao của hàm mũi tên bên trong.
Khả năng đọc mã
Mặc dù các chức năng mũi tên hữu ích như các cuộc gọi lại, nhưng chúng cũng được sử dụng để giữ cho mã rõ ràng và ngắn gọn. Trong phần trên, bạn có thể thấy rằng việc sử dụng hàm mũi tên giúp dễ dàng thấy rõ điều gì sẽ xảy ra khi tin nhắn bị trì hoãn chức năng được gọi.
Khi các chức năng trở nên phức tạp hơn, việc có một chút rõ ràng có thể làm cho mã dễ đọc hơn nhiều. Khi soạn thảo các đối tượng, điều này có thể làm cho mã đơn giản hơn khi thêm các chức năng ngắn:
class counter {
_count = 0;
increment = () => {
this._count += 1;
}
decrement = () => {
this._count -= 1;
}
count = () => {
return this._count;
}
}let ct = new counter();
Vai trò trong lập trình hướng đối tượng
Mặc dù các hàm mũi tên của JavaScript là một phần không thể thiếu trong lập trình hàm, nhưng chúng cũng có một vị trí trong lập trình hướng đối tượng. Các hàm mũi tên có thể được sử dụng trong các khai báo lớp:
class orderLineItem {
_LineItemID = 0;
_Product = {};
_Qty = 1; constructor(product) {
this._LineItemID = crypto.randomUUID();
this._Product = product
}
changeLineItemQuantity = (newQty) => {
this._Qty = newQty;
}
}
Việc sử dụng hàm mũi tên để khai báo các phương thức trong khai báo lớp không làm thay đổi hành vi của hàm trong lớp. Tuy nhiên, bên ngoài lớp, nó hiển thị chức năng, cho phép nó được sử dụng bởi các lớp khác.
Các chức năng thông thường không thể được truy cập bên ngoài khai báo lớp mà không được gọi. Điều này có nghĩa là trong khi các khai báo lớp khác có thể kế thừa các chức năng này, chúng không thể được truy cập trực tiếp để soạn các lớp khác.
Khi nào bạn nên sử dụng các hàm mũi tên của JavaScript?
Các hàm mũi tên của JavaScript là một tính năng cực kỳ mạnh mẽ giúp các nhà phát triển có nhiều quyền kiểm soát hơn đối với phạm vi mà một hàm có quyền truy cập. Biết khi nào một cuộc gọi lại nên có quyền truy cập vào phạm vi của cha mẹ nó và khi nào thì không, có thể giúp nhà phát triển xác định loại khai báo nào sẽ sử dụng.
Các hàm mũi tên cung cấp cho các lập trình viên một cách rõ ràng và ngắn gọn để viết các cuộc gọi lại mà không để lộ các phần của phạm vi cần được ẩn. Chúng cũng cho phép tạo ra các tác phẩm đơn giản và sạch sẽ, tiếp tục cho phép lập trình chức năng trong JavaScript.
Các nhà phát triển JS phải nhận thức được sự khác biệt giữa hai cú pháp và lưu ý cú pháp nào phù hợp khi khai báo các hàm của họ.