+1

Hoisting trong JavaScript là gì?

Tôi từng nghe nhiều người nói: "JavaScript hoists (kéo lên) các biến và hàm", và thật lòng mà nói… điều đó chỉ khiến tôi rối thêm.

Nhưng một khi tôi thấy nó hoạt động thực tế, thì mọi thứ mới thực sự sáng tỏ.

Trong bài viết này, tôi sẽ giải thích hoisting thực sự là gì, nó hoạt động như thế nào phía sau hậu trường, và cách nó có thể khiến bạn "vấp ngã" trong các buổi phỏng vấn.

Hoisting là gì?

Hoisting là cách JavaScript đọc code của bạn trước khi nó thực sự thực thi.

Ngay khi chương trình bắt đầu, JavaScript sẽ quét nhanh toàn bộ mã nguồn và dành sẵn không gian bộ nhớ cho tất cả các biến và hàm mà bạn đã khai báo.

  • Với các biến được khai báo bằng var, JavaScript gán cho chúng giá trị undefined.
  • Với các hàm được khai báo bằng từ khóa function, toàn bộ phần thân hàm sẽ được lưu trữ, vì vậy bạn có thể gọi hàm đó trước cả khi nó được viết trong mã nguồn.

Quá trình thiết lập ngầm này được gọi là hoisting.

Ví dụ minh họa

Ví dụ 1: Hoisting với var

console.log(name); 
var name = "John";

Kết quả:

undefined

JavaScript thực chất hiểu đoạn mã như sau:

var name;
console.log(name); // undefined
name = "John";

Ví dụ 2: Sử dụng biến chưa được khai báo

console.log(age); 
var name = "John";

Kết quả:

ReferenceError: age is not defined

Tại sao? Vì age chưa từng được khai báo, nên không có vùng nhớ nào được cấp cho nó trong quá trình quét ban đầu.

Ví dụ 3: Hàm khai báo được hoisting hoàn toàn

sayHello();

function sayHello() {
  console.log("Hello!");
}

Kết quả:

Hello!

Toàn bộ hàm được hoisting lên đầu.

Ví dụ 4: Arrow function không được hoisting

greet(); // ❌ TypeError: greet is not a function

var greet = () => {
  console.log("Hi there!");
};

Mặc dù greet được khai báo bằng var, nhưng arrow function hoạt động giống như biến, không như một hàm được hoisting

Ghi chú: letconst không giống var

console.log(age); // ❌ ReferenceError

let age = 25;

Tại sao vẫn lỗi dù đã khai báo age?

Đó là vì một khái niệm gọi là "Temporal Dead Zone (TDZ)" – vùng chết tạm thời.

“Ừ, tôi biết age tồn tại, nhưng bạn không thể chạm vào nó cho đến khi tôi thực sự đến dòng khai báo.”

Vì vậy, không giống như var, JavaScript không gán giá trị undefined tạm thời cho letconst. Bạn sẽ gặp lỗi ReferenceError nếu cố gắng truy cập chúng quá sớm.

Hy vọng qua bài viết này các bạn đã hiểu rõ được khái niệm Hoisting trong JavaScript là gì.


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.