- Khai báo hàm trong JavaScript có thể được thực hiện theo nhiều cách như dùng từ khóa
function, biểu thức hàm, và hàm mũi tên
- Khai báo hàm được áp dụng hoisting, nên có thể được tham chiếu ở bất kỳ vị trí nào trong mã
- Hàm Arrow (mũi tên) có ưu điểm là cú pháp ngắn gọn, nhưng có những khác biệt quan trọng như không có ràng buộc
this/arguments/super
- Hàm tạo, generator, method không phù hợp để dùng hàm mũi tên
- Với callback đơn giản hoặc hàm ẩn danh, hàm mũi tên phù hợp hơn
Function Declarations, Function Expressions, and Arrow Functions
- Trong JavaScript, có thể định nghĩa hàm theo ba cách: khai báo hàm (statement), biểu thức hàm (expression), và hàm mũi tên (arrow function)
- Khai báo hàm gắn trực tiếp tên như
function isVowel(chr) { ... }, và có thể được tham chiếu ở bất kỳ đâu trong mã (hoisting). Trong stack trace và khi debug, tên hàm cũng được hiển thị rõ ràng
- Biểu thức hàm có dạng gán một hàm ẩn danh cho biến như
const takeWhile = function(predicate, arr) { ... }
- Biểu thức hàm cũng có thể có tên nội bộ, nhưng tên đó không được ràng buộc vào scope bên ngoài, mà chủ yếu được dùng để lần vết lỗi trong stack trace
Hoisting and Naming
- Câu lệnh khai báo hàm được JavaScript engine hoist, nên vẫn hoạt động ngay cả khi được gọi trước chỗ khai báo
- Biểu thức hàm ẩn danh chỉ có thể được gọi sau khi biến đã được gán
- Để debug tốt hơn, việc đặt tên hàm một cách tường minh có thể có lợi trong stack trace
Arrow Functions
Practical Example: this, constructor, và generator
- Có ví dụ minh họa sự khác biệt giữa hàm thông thường và hàm mũi tên trong cách xử lý
this
- Khi dùng làm method trong object, hàm thông thường sẽ có
this trỏ tới chính object đó, còn hàm mũi tên sẽ trỏ tới undefined hoặc this của scope bên ngoài
- Nếu định nghĩa hàm tạo bằng hàm mũi tên thì sẽ phát sinh
TypeError
- Generator function bắt buộc phải dùng cú pháp
function*
Nên chọn cú pháp hàm nào khi nào?
- Cần generator (dùng
yield) → dùng function*
- Cần sử dụng
this → dùng từ khóa function hoặc method của class
- Cần hoisting hoặc muốn tăng khả năng đọc ở cấp độ cao hơn → dùng câu lệnh khai báo hàm
- Nếu không thuộc các trường hợp trên → hàm mũi tên sẽ có lợi thế hơn nhờ sự ngắn gọn
Kết luận
- Với hàm trong JavaScript, nên chọn cú pháp dựa trên mục đích sử dụng, việc có cần
this hay không, và có phải constructor/generator hay không
- Với callback thường ngày / hàm đơn giản, hàm mũi tên là lựa chọn tốt nhất
- Với method của object / constructor / generator, cần dùng cú pháp
function
- Nếu cần hoisting hoặc sự linh hoạt về thứ tự khai báo, thì câu lệnh khai báo hàm sẽ có lợi hơn
3 bình luận
Không chỉ là bản chất mà còn là việc có hay không có
prototype...Cả cách tham chiếu của hàm bậc cao được tạo ra cũng vậy...
() => ❤️