+8

Hoisting trong JavaScript

Điều khiến JavaScript khó hiểu với những người mới hay chuyển từ ngôn ngữ khác qua chính là JavaScript cho phép sử dụng biến và hàm ngay cả trước cả khi bạn khai báo chúng.

Ví dụ ở đoạn code này:

1. console.log(a)
2. aFunction()
3. 
4. var a = 3;
5. function aFunction() {
6. 	console.log("Hello")
7. }

Chương trình khi chạy không báo lỗi gì và kết quả in ra ở Console là:

undefined
Hello

Lưu ý ở đây mình dùng var , nếu sử dụng let hay const thì sẽ bị lỗi Uncaught ReferenceError: x is not defined vì với let hay const của ES6 thì chỉ sau khi bạn khai báo mới sử dụng được chúng.

Vậy điều gì đã khiến bạn có thể truy cập vào các biến và hàm ngay cả khi chúng chưa được khai báo?

Chính là cơ chế Hoisting trong JavaScript.

Vậy cụ thể thì hoisting là như thế nào?

Bạn có nhớ hai giai đoạn của một “Execution Context”Memory CreationCode Execution đã được giới thiệu trong bài “Điều gì xảy ra khi chạy một chương trình JavaScript” không?

Hoisting trong JavaScript được thực hiện trong giai đoạn cấp phát bộ nhớ – Memory Creation. Các biến và hàm sẽ được cấp bộ nhớ trước khi code được thực thi, biến được cấp bộ nhớ với giá trị undefined , còn hàm thì sẽ được cấp bộ nhớ cho toàn bộ nội dung bên trong hàm f aFunction().

Vì thế, bước vào giai đoạn thực thi Code Execution, thì các giá trị này đã có sẵn để sử dụng, nên gọi các hàm và biến này đã được hoist lên trước khi code được thực thi.


Bạn có thể kiểm tra trực tiếp trên devTools bằng cách đặt một breakpoint ngay tại dòng số 4, ngay trước khi code của biến và hàm được khai báo.

Khi chương trình chạy, gặp breakpoint dừng lại, hãy kiểm tra tab Global và tìm a , aFunction , tại đây tìm thấy biến a và hàm aFunction đã được cấp phát bộ nhớ và sẵn sàng để sử dụng.

Một lưu ý ở đây, nếu aFunction được khai báo ở dạng biểu thức dưới tên một biến

var aFunction = function() {}

thì aFunction sẽ có giá trị ban đầu là undefined như với một biến bình thường, và chương trình này sẽ báo lỗi.

Hoisting trong JavaScript sẽ dễ gây hiểu nhầm nếu bạn không hiểu về JavaScript Engine nên bạn cần tìm hiểu cơ chế này để dễ debug chương trình của mình nhé.

Thêm nữa, ở phiên bản ES6, cung cấp let và const để yêu cầu bạn chỉ sử dụng biến sau khi đã khai báo chúng nên sẽ tránh được các sử dụng không mong đợi như trên.

Vì thế, bạn nên ưu tiên sử dụng let và const thay thế cho var.

(Ref series Namaste JavaScript)

Bài viết gốc nằm ở blog cá nhân của mình, mời bạn ghé chơi.


If you think these contents are helpful, you could send me an encouraging by:

🤘 Chat with me 🤘

See you around, friends!


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí