
JavaScript Hoisting: Giải mã cơ chế hoạt động thực sự bên trong Engine
Bạn đã bao giờ thắc mắc tại sao JavaScript có thể truy cập biến hoặc hàm trước khi chúng được định nghĩa? Hãy cùng hi_dev đi sâu vào cơ chế Hoisting, tìm hiểu về Memory Creation Phase và Execution Context để hiểu rõ bản chất kỹ thuật đằng sau hiện tượng này.
Bài viết được dịch và tổng hợp từ tin tức gốc. Bạn có thể đọc bài viết gốc bằng tiếng Anh tại đây.
Điểm tin nhanh:
- Hoisting không phải là việc di chuyển code lên đầu file, mà là quá trình cấp phát bộ nhớ trước khi thực thi.
- JavaScript thực hiện theo mô hình 2 bước: Memory Creation (tạo bộ nhớ) và Execution (thực thi).
- Các biến
letvàconstbị đưa vào Temporal Dead Zone (TDZ), khiến chúng không thể truy cập trước khi khởi tạo.
Hoisting là gì? Sự thật đằng sau những lời đồn đại
Nhiều lập trình viên thường nghe câu nói: "JavaScript tự động đưa biến và hàm lên đầu file". Tuy nhiên, đây là một cách hiểu sai lệch về mặt kỹ thuật. Thực tế, không có dòng code nào bị di chuyển vật lý. JavaScript Hoisting là kết quả trực tiếp của cách JavaScript Engine chuẩn bị bộ nhớ trước khi bắt đầu chạy bất kỳ dòng code nào của bạn.
Mô hình 2 bước của JavaScript Engine
Để hiểu rõ tại sao Hoisting xảy ra, chúng ta cần nắm vững quy trình xử lý của Engine:
| Giai đoạn | Nhiệm vụ chính |
|---|---|
| Memory Creation Phase | Quét code, định danh biến/hàm, cấp phát bộ nhớ (Hoisting xảy ra ở đây) |
| Execution Phase | Chạy code từng dòng, gán giá trị và thực thi hàm |
Sơ đồ quy trình thực thi (Execution Context)
Khi một đoạn mã JavaScript chạy, quy trình diễn ra như sau:
[Source Code] ➔ [Memory Creation] ➔ [Execution Context] ➔ [Call Stack]
Phân tích các trường hợp Hoisting cụ thể
1. Biến var
Khi Engine gặp var a = 10;, nó tách làm hai phần:
- Declaration: Cấp phát bộ nhớ cho
avà khởi tạo giá trịundefined. - Assignment: Gán giá trị
10trong giai đoạn thực thi.
Đó là lý do tại saoconsole.log(a)trả vềundefinedthay vì lỗi.
2. Function Declarations
Khác với var, toàn bộ định nghĩa hàm được lưu trữ trong bộ nhớ ngay từ đầu. Do đó, bạn có thể gọi hàm trước khi khai báo.
3. Function Expressions
Khi bạn gán hàm cho một biến (var sayHi = function() {...}), Engine chỉ hoist biến sayHi với giá trị undefined. Khi bạn gọi sayHi(), nó sẽ trả về TypeError vì undefined không phải là một hàm.
4. let và const với Temporal Dead Zone (TDZ)
Nhiều người nghĩ let và const không bị Hoisting, nhưng thực tế chúng có. Sự khác biệt là chúng không được khởi tạo giá trị undefined. Chúng nằm trong Temporal Dead Zone (TDZ) – vùng không thể truy cập cho đến khi dòng khai báo được thực thi.
Kết luận
Hoisting không phải là tính năng "ma thuật", mà là quy trình chuẩn bị bộ nhớ ngăn nắp của JavaScript Engine. Hiểu rõ cơ chế này giúp bạn viết code sạch hơn, tránh các lỗi ReferenceError không đáng có. Nếu bạn đang làm việc với các hệ thống phức tạp, việc nắm vững cách Engine quản lý bộ nhớ cũng quan trọng như việc làm chủ các công cụ như L: Runtime thế hệ mới cho ngôn ngữ K và Q hay các kỹ thuật tối ưu hóa khác.
Do you like this post?
Upvote to push this post higher on the community feed
