Mở đầu
Những người mới bắt đầu tìm hiểu về Javascript sẽ thắc mắc khi gặp một số trường hợp sử dụng biến rồi mới khai báo sau. Vì theo quy tắc chung của đa số các ngôn ngữ lập trình, để sử dụng một biến thì ta phải khai báo nó trước.
Làm được như thế vì trong Javascript có cơ chế Hoisting, trong bài viết này chúng ta sẽ tìm hiểu cơ chế Hoisting trong Javascript. Để hiểu về Hoisting trước tiên phải bạn phải hiểu về Scope trong Javascript.
Hoisting là gì ?
Hoisting là cơ chế mặc định của JavaScript để di chuyển tất cả các biến và hàm khi khai báo lên đầu scope trước khi chúng được thực thi.
Lưu ý đối với cơ chế này nó chỉ di chuyển khai báo, còn việc gán giá trị thì giữ nguyên.
Hoisting variables
Vòng đời của biến trong javascript bao gồm các giai đoạn sau:
- Khai báo
- Khởi tạo giá trị mặc định
- Gán một giá trị cho biến được khởi tạo
Tuy nhiên, vì Javascript cho phép ta gán giá trị ngay khi khai báo biến. Đây là cách chúng ta thường làm:
var hoist = 500;
Các bạn thử đoán xem kết quả của đoạn code sau đây là gì:
console.log(hoist);
var hoist = 500;
Mình đoán sẽ có nhiều người nghĩ rằng kết quả là ReferenceError: hoist is not defined
vì ta đang truy cập vào một biến chưa được khai báo trước đó. Nhưng không, kết quả của đoạn code trên là undefined
.
LOL vì sao lại thế ???
Cơ chế Hoisting của Javasript đã đưa khai báo biến lên trên cùng. Dưới đây mình sẽ mô tả những gì đã xảy ra.
var hoist; \ hoist mới được khai báo nên giá trị của hoist là undefined.
console.log(hoist);
var hoist = 500;
Nếu bạn sẽ thắc mắc khai báo được đưa lên trên cùng, trên cùng là ở đâu. Trên cùng là vị trí cao nhất trong scope hện tại (current scope).
Ví dụ:
function hoist() {
console.log(mess);
var mess ='Hello World!';
}
hoist(); //Output: undefined
Function trên tương tự như thế này:
function hoist() {
var mess; // Biến mess được khai báo ở trên cùng của scope fuction hoist()
console.log(mess);
var mess ='Hello World!';
}
hoist(); //Output: undefined
Hoisting functions
Trong Javascript có hai loại hàm là:
- Khai báo hàm (Function Declaration)
- Biểu thức hàm (Function Expression)
Với function declarations thì bạn khai báo bắt đầu là function operator, sau đó gán cho nó một cái tên như ví dụ dưới đây:
// Function declaration
function speak() {
console.log("Hello");
}
Còn với function expressions thì bạn tạo một variable sau đó gán cho nó với một anonymous function như ví dụ sau đây:
// Function expression
var speak = function () {
console.log("Hello")
};
Trong Javascript thì Function declarations có thuộc tính Hoisting, còn Function expression thì không.
Chúng ta cùng xem các ví dụ sau đây:
//Function declaration
speak(); //Function declaration có Hoisting nên output là undefined
function speak() {
console.log("Hello");
}
// Function expression
speak(); //TypeError: speak is not a function
var speak = function () {
console.log("Hello")
};
Haizzz… tới đây bạn cảm thấy Hoisting như thế nào. Cá nhân mình thì thấy Hositing có thể dẫn để code của chúng ta cẩu thả và khó quản lý. Và phiên bản ES6 sinh ra nhằm cải tiến các vấn đề Javascript gặp phải.
Tổng kết
Trên đây mình đã giải thích về Hoisting trong Javascript.
Chỉ ra một phần sự khác nhau giữa Function expression và Function declaration.
Tham khảo
https://dmitripavlutin.com/variables-lifecycle-and-why-let-is-not-hoisted/https://xdevclass.com/hieu-sau-ve-hoisting-scope-trong-javascript/
Nguồn: viblo.asia