Hoisting trong Javascipt

Cập nhật: Lượt xem: 282 [ Javascript ]

Hoisting trong Javascipt

Hoisting trong Javascipt

Ví dụ

Hoisting là một khái niệm cơ bản và đặc thù của Javascipt, chúng ta cần hiểu rõ khái niệm này để tránh gặp phải việc chương trình của mình không chạy như mong muốn hoặc gặp những lỗi khó hiểu.

Trong hầu hết các ngôn ngữ lập trình, bạn phải định nghĩa một function trước khi bạn gọi đến nó.

calAverage(1,5);

function calAverage(x, y) {
  var answer = (x + y)/2;
  return answer;
}

Ở đây mình ví dụ viết một hàm tính giá trị trung bình của 2 số bằng js, nếu như mình viết bằng một ngôn ngữ khác (pascal chẳng hạn) thì việc dùng hàm calAverage sẽ thông báo lỗi vì chưa được định nghĩa.

Tuy nhiên khi mình viết bằng JS thì việc gọi hàm như trên hoàn toàn bình thường và chạy ngon lành, vậy tại sao lại như thế?

Hoisting là gì?

Hoisting trong JS về cơ bản là chỉ việc trước khi bất kỳ đoạn code nào được thực thi thì tất cả định nghĩa hàm được "kéo" lên trên đầu của scope hiện tại.

Hmm, đoạn code của bạn thì trông vẫn sẽ như thế thôi nhưng điều thực sự xảy ra đằng sau nó là mọi định nghĩa hàm và biến trong code của bạn sẽ được thêm vào bộ nhớ trong giai đoạn compile.

Vậy hoisting với biến thì sao?

Chúng ta cùng xét một ví dụ sau:

myNickname = 'deptrailoitaiai';
alert(myNickname);
var myNickname;

Ở VD này, việc hoisting sẽ được thực hiện và code của chúng ta sẽ chạy bình thường, việc khai báobiến myNickname sẽ được chuyển lên đầu như sau:

var myNickname;
myNickname = 'deptrailoitaiai';
alert(myNickname);

JS không hoisting phép gán và khởi tạo biến

Chúng ta xét đến ví dụ tiếp theo

function sayHello() {
  alert(hello);
  var hello = 'xinchao';
}

Theo như các ví dụ trước đó thì chúng ta sẽ mong chờ việc JS sẽ "kéo" việc khởi tạo và gán var hello = 'xinchao'lên trước hàm alert() và bắn ra alert là helllo, thế nhưng đời không như là mơ, khi chạy đoạn code trên thì nó sẽ ra kết quả như sau:

2a5db697-a2d3-4210-a51b-c98c61e44ad2

Điều này xảy ra là do JS không hoisting phép gán và khởi tạo biến, đoạn code trên của chúng ta thực chất sẽ được JS xử lý như sau:

function sayHello() {
  var hello;
  alert(hello);
  hello = 'xinchao';
}

Vì vậy, alert sẽ được gọi trước khi biến hello được gán cho nên hello vẫn là undefined.

Thông thường, để tránh "bug" không đáng có này, mọi người thường declare biến và hàm lên đầu của scope, vừa tránh được bug, vừa thể hiện đúng việc chương trình sẽ chạy như thế nào.

Lời kết

Mong rằng qua bài viết này các bạn sẽ hiểu rõ hơn về khái niệm "hoisting" ở trong JS và tránh được những bugs không đáng có khi sử dụng ngôn ngữ lập trình phổ biến và cũng lắm người ghét nhất nhì hành tinh này.

Tài liệu tham khảo

https://www.w3schools.com/js/js_hoisting.asp

https://developer.mozilla.org/vi/docs/Tu-dien-thuat-ngu/Hoisting