Storyofsu

Hoisting trong JavaScript

Javascript được mệnh danh là "The World's Most Misunderstood Programming Language - Ngôn ngữ lập trình sai lầm nhất". Một trong số những cái hay ho mà làm cho javascript trông như có vẻ sai sai đó chính là hoisting

Nếu bạn là người mới học hoặc không code javascript nhiều thì rất có thể bạn sẽ thấy lạ lẫm với khái niệm hoisting. Vì vậy nếu bạn muốn tìm hiểu sâu hơn về javascript thì bạn nên biết về khái niệm hoising này nhé.

Khái niệm hoisting

Về cơ bản, khi Javascript compile code, tất cả các biến được khai báo sử dụng var sẽ được nâng lên trên cùng của function hoặc trên cùng của scope nếu nó được khai báo bên ngoài function. Và việc đẩy khai báo biến lên đầu được gọi là hoisting.

Khai báo function cũng là hoisting, thậm trí nó sẽ được đẩy lên trên cả khai báo biến.

Để hiểu rõ hơn, chúng ta đi xét một vài ví dụ sau.

console.log(name)
var name = 'th';

Kết quả của console.log(name) là gì?

  1. Uncaught ReferenceError: name is not defined
  2. th
  3. undefined

Kết quả chính xác là đáp án thứ 3.

Như đã nới ở trên, khi biên dịch phần khai báo biến sẽ được đẩy lên trên. Tuy nhiên điều quan trọng cần các bạn cần chú ý là chỉ phần khai báo biến được đẩy lên trên, không phải cả phần gán giá trị

Kết quả là undefined là vì khi biên dịch việc khai báo biến name sẽ được đặt lên đầu, và nó sẽ nằm trên câu lệnh console.log(name), chính vì vậy sẽ không bị lỗi Uncaught ReferenceError: name is not defined vì khi console.log(name) thì biến name đã tồn tại. Nhưng biến name lúc này chỉ được khai báo chứ chưa được gán giá trị, chính vì vậy giá trị nó là undefined

Để dễ hiểu hơn thì ví dụ trên sau khi biên dịch sẽ có thứ tự như thế này.

var name
console.log(name)
name = 'th';

Giờ thì rõ rồi phải không nào.

Xét ví dụ với function

function hey() {
    console.log('hey ' + name);
};
hey();
var name = 'th';

Khi chạy name khi được in ra sẽ vẫn là undefined. Vì nó thực sự sẽ như sau khi biên dịch

function hey() {
    console.log('hey ' + name);
};
var name;
hey();
name = 'th';

Vào thời điểm hàm hey() được gọi. Biến name đã được khai báo, nhưng chưa được gán giá trị do dậy kết quả là undefined. Có một vài biến thể của điều này, xảy ra khi khai báo biến trong biểu thức IIFE . IIFE chắc hẳn cũng là một khái niệm lạ lẫm, nhưng mình sẽ nói đến nó trong một bài nào đó sau này.

Tuy hoisting sẽ làm cho việc dụng trước - khai báo sau lại không gây ra lỗi 😃)))), nhưng sẽ là tốt nhất nếu chúng ta đẩy việc khai báo biến trên đầu,giống như hoisting làm, điều đó sẽ làm code dễ đọc hơn và giảm thiểu được những lỗi không đáng có.

Vậy đối với let và const thì sao?

All declarations (var, let, const, function, function*, class) are "hoisted" in JavaScript. Tất cả các khai báo var, let, const, function, function*, class trong Javascript đều được hoisting.

Sự khác biệt giữa khai báo var so với let và const là giá trị khởi tại. Đối với var giá trị khởi tạo là undefined trong khi đó với let và const sẽ thorw ra lỗi Reference error khi bạn chỉ khai báo mà chưa gán giá trị.

Có một chú ý nhỏ là vì const phải được gián giá trị cùng với việc khai báo. Nên khi hoisting sẽ không được chuyển thành dạng const name; name = 'th'; mà sẽ chỉ là const name = 'th'. Lý do thì hết sức rõ ràng rồi, const là hằng số mà, nó đâu có gán được giá trị khác, nên khi khởi tạo const sẽ được gán giá trị luôn.

Kết luận

Một khái niêm đơn giản, nhưng sẽ rất quan trọng nếu bạn muốn học Javascript một cách bản. Ngoài hoisting ra còn nhiều khái niệm khác để các bạn tìm hiểu nhé

  • IIFE
  • First-class functions
  • Function Expression
  • Function scope
  • Lexical scope
  • Closure
  • Block scope
  • this
  • Prototype
  • New
  • Function statement
  • Function constructor
Registration Login
Sign in with social account
or
Lost your Password?
Registration Login
Sign in with social account
or
A password will be send on your post
Registration Login
Registration