Bài 6: Anonymous Function và Closure

Trong bài viết trước, khi tìm hiểu về cách viết Hàm trong Javascript , các bạn sẽ thấy rằng nó hoàn toàn không khác gì các ngôn ngữ phổ biến như C++, C#, Java...nhưng trong nó còn hỗ trợ một cách viết khác cũng không kém phần thú vị và nó có tên gọi là Anonymous Function, tuy nhiên ở một số trường hợp nó lại trở thành khái niệm khác và có tên gọi là Closure. Vậy do đâu mà có sự khác biệt như vậy giữa Anonymous Function va Closure? Các bạn hãy cùng tìm hiểu với tôi nhé.

Anonymous Function và Closure

 

Bài viết đang củng cố lại học thuật, vì có kiến thức lúc tác giả viết bài này vẫn chưa chính xác. Độc giả vui lòng quay lại khi khác. Xin cám ơn các bạn độc giả đã quan tâm.

Để giải thích các khái niệm này và hiểu được nó sẽ mất rất nhiều thời gian của các bạn. Tuy nhiên, các bạn có thể hiểu đơn giản như sau:

Anonymous Function (Hàm vô danh)

Kết quả:

Closure (Bao đóng)

(Vui lòng bật F12 trên Chrome/Firefox và chuyển sang Tab Console để thấy kết quả)

Kết quả:

Khi đến với 2 kiểu dữ liệu cuối cùng, chắc hẳn các bạn sẽ có nhiều thắc mắc về nó rất nhiều. Vậy đâu là sự khác biệt giữa Anonymous Function và Closure?

Anonymous Function thực chất chỉ là một hàm không có tên gọi, thường được sử dụng khi xử lý các công việc có quy mô nhỏ, vì thế không cần thiết phải khởi tạo tên định danh cho hàm này. Giúp nó có tốc độ xử lý nhanh hơn hàm truyền thống phải có tên định danh.

Closure có các tính chất của Anonymous Function đó chính là không cần tên định danh cho nó. Nhưng để được gọi là Closure thì trong nó phải sử dụng ít nhất là một biến không phụ thuộc vào phạm vi hàm mà chúng ta định nghĩa.

Hãy xem qua 3 ví dụ chi tiết sau đây:

VD 1: Các trường hợp của Anonymous Function

Kết quả:

Qua ví dụ trên, bạn đã phần nào hiểu rõ về Anonymous Function rồi có đúng không? Nó chỉ được gọi là Anonymous Function khi nó không sử dụng biến nào bên ngoài hàm hay nói cách khác là không được phép sử dụng biến toàn cục trong hàm này.

VD 2: Các trường hợp của Closure

1. Kết hợp Anonymous Function và Closure

Kết quả:

  • Biến “anonymous” được xem là Anonymous Function bởi vì chính nó không dùng biến bên ngoài hàm được định nghĩa.
  • Biến “closure” được xem là “Closure” bởi vì nó đã sử dụng biến “a” (Biến toàn cục trong hàm “anonymous”) thuộc “anonymous” có phạm vi ảnh hưởng rộng hơn trong “closure” cho phép “closure” có thể gọi giá trị bên ngoài và tác động đến giá trị đó, cụ thể ở đây là biến “a”.
  • Biến “b” trong “closure” được định nghĩa trong phạm vi của “closure” vì thế, nếu nó được dùng trong “anonymous” tức là bên ngoài “closure” sẽ không được phép truy cập vào hoặc tác động được vào giá trị của nó.
  • Biến “b” trong “anonymous” được định nghĩa là biến toàn cục (khi không có từ khóa “var”) có thể được truy xuất ở nơi không được định nghĩa lại biến “b” như trong “closure” đã định nghĩa biến “b” như trước đó. Và nó có thể cho phép truy xuất cả bên ngoài “anonymous” mà không gặp bất cứ lỗi nào. Đó là một trong những vấn đề rất quan trọng khi dùng từ khóa “var” và khi không dùng từ khóa “var”. Vì thế các bạn đã thấy biến “b” trong “closure” và biến “b” ở “anonymous” được định nghĩa lại hoàn toàn không tác động gì được trong phạm vi của “closure”. Các bạn có thể xem ví dụ về vấn đề này rõ hơn ở Ví dụ bên dưới.

2. Phạm vi của biến trong và ngoài Closure

Kết quả:

  • Như ví dụ bên trên mà tôi đã viết, các bạn sẽ thấy được rõ ràng phạm vi của biến được sử dụng trong ví dụ này.
  • Trong đó, biến “c” được định nghĩa là biến toàn cục thay vì cục bộ trong một hàm cho dù nó có từ khóa “var” bởi vì nó đã được định nghĩa bên ngoài tất cả các hàm bao hàm lấy nó, nên nó cũng được xem là biến toàn cục trong trường hợp này.
  • Và khi biến “c” được tác động trong “closure”, nó cũng sẽ thay đổi giá trị của biến “c” bên ngoài nó bởi vì nó là biến toàn cục.
  • Biến “d” được khởi tạo trong “closure” chỉ được hiểu trong phạm vi của “closure” nên vì thế các bạn sẽ thấy lỗi khi chạy đoạn chương trình tôi cung cấp, vì nó không tìm thấy biến “d” ở phạm vi ngoài “closure”.
  • Tương tự với hàm “child_closure”, nó cũng đã sử dụng biến bên ngoài phạm vi của nó đó chính là biến “c” toàn cục và biến “d” ở “closure”. Và khi đó, biến “d” nằm trong phạm vi của “closure” và khi đó “child_closure” cũng nằm trong phạm vi của “closure” vì thế biến “d” hoàn toàn cũng được phép truy cập vào biến “d” của “closure” và thay đổi giá trị của nó.

Qua các ví dụ trên, chắc hẳn nếu bạn nào vẫn còn bối rối với phạm vi của biến có từ khóa “var” và không có từ khóa “var” hoặc với phạm vi của “Closure”. Tôi đề nghị các bạn nên thử cách viết và cách sử dụng biến trong Javascript để có thể hiểu rõ về nó hơn thay vì chỉ đọc và ngẫm. Như vậy bạn sẽ có trải nghiệm về nó một cách chính xác hơn.

Sau khi tìm hiểu về Anonymous Function và Closure trong Javascript (JS) chắc hẳn các bạn đã thấy được nhiều điều thú vị từ nó. Trong các bài viết sau, chúng ta sẽ tập trung vào tìm hiểu Javascript và HTML DOM cũng như các ví dụ thực tế và một số thủ thuật khi viết code trong Javascript và giải đáp thắc mắc một số cách ghi tắt trong Javascript.

(Visited 3,119 times, 1 visits today)

Bình luận

các bình luận