+2

Are you really understand Javascript ?

Javascript Hoisting

image.png

Mình chắc rằng, có nhiều bạn đã từng đọc về Hoisting trong javascript ,nhưng có thể các bạn chưa hoàn toàn hiểu về nó. Vậy Hoisting trong javascript là gì và bạn có thực sự hiểu về nó như những gì bạn nghĩ không ? Cùng tìm hiểu nhé

1. Javascript Hoisting

Để hiểu rõ về Hoisting, đầu tiên ta phải hiểu về Execution Context . Vậy Execution Context là gì ?

Để đơn giản hóa , ta hãy hiểu Execution Context là thứ dùng để quản lí dòng code nào đang được chạy, hay hãy hiểu nó là 1 wrapper giúp bạn quản lí được đoạn code nào đang được chạy khi bạn chạy file javascript của mình .

Execution Context có 2 giai đoạn , giai đoạn 1 là Creation phase , giai đoạn 2 là Execution phase.

Ta hãy tạm thời bỏ qua 2 phase này cụ thể là gì và dùng để làm gì,tôi sẽ giải thích cụ thể hơn về nó ở 1 bài viết khác trong tương lai.

Nhiều người tưởng rằng Hoisting là chuyển các đoạn code khai báo variables và function lên đầu trang nhưng thực ra không phải.Điều thực sự xảy ra là khi các dòng code của bạn được biên dịch,1 Execution Context sẽ được tạo ra.Đầu tiên nó sẽ tiến vào phase 1 (Creation phase).Ở phase 1 này, trình phân tích sẽ chạy qua các đoạn code của bạn và set up vùng nhớ để lưu các variables và function của bạn vào trong đó.Sau đó nó sẽ tiến đến phase 2 (Execution phase). Về cơ bản phase 2 sẽ thực thi các dòng code của bạn, khi đó nếu ta gọi hàm hoặc biến trước khi nó được khai báo , trình biên dịch sẽ có thể truy cập vào hàm hoặc biến đó (vì nó đã được lưu vào vùng nhớ từ trước đó khi đang ở phase 1 rồi) .Có thể đọc đến đây bạn sẽ thấy hơi khó hiểu. Đừng lo lắng, bây giờ chúng ta sẽ đi vào ví dụ để hiểu rõ hơn những gì tôi vừa trình bày bên trên

2. Ví dụ

2.1 Hosting of function

hello()

function hello(){
    console.log("Hello There")
}

Output: Hello There

Giải thích : Như tôi đã trình bày bên trên, khi bạn biên dịch code javascript của mình (chạy code javascript) đầu tiên nó sẽ tạo 1 Execution Context và tiến vào phase 1.Khi ở phase 1 này,function hello() sẽ được lưu vào 1 ô nhớ,sau đó Execution Context tiếp tục tiến vào phase 2.Khi ở phase 2 này, nó sẽ chạy code javascript của bạn,Ở dòng đầu tiên trình biên dịch code thấy rằng bạn đang gọi đến function hello() , mặc dù khi này function hello() chưa được khai báo nhưng nó vẫn có thể truy cập vào được, đó là nhờ function hello() đã được lưu vào 1 ô nhớ khi Execution Context còn đang ở phase 1 , do đó nó thể truy cập được vào function hello() từ trước cả khi nó được khai báo

2.2 Hosting of variables

Ví dụ 1:

console.log(a)
var a = "Hello there"

Output: undefined

Giải thích : Có thể bạn đang thắc mắc tại sao output lại là undefined đúng không, hãy để tôi giải thích cho bạn, Hoisting của variables có phần khác biệt so với của function, đó là khi Execution Context đang ở phase 1 , mặc dù nó có lưu variables vào ô nhớ, nhưng nó không lưu giá trị của variables đó vào mà mặc định sẽ gán giá trị cho variables đó là undefined. Cụ thể trong ví dụ trên,var a = "Hello there", variables a khi được lưu vào trong ô nhớ sẽ không được lưu với value là "Hello there",thay vào đó value mà nó được lưu là undefined.Vậy nên tại thời điểm trình biên dịch chạy dòng code console.log(a) , khi này biến a vẫn chưa được khai báo nên trong ô nhớ vẫn đang có giá trị là undefined, vậy nên output ta nhận được là undefined

Ví dụ 2: nhưng nếu tôi console.log lại variables a thêm 1 lần nữa sau dòng khai báo var a , output sẽ là gì ?

console.log(a)
var a = "Hello there"
console.log(a)

Output: undefined Hello there

Giải thích : ouput đầu tiên là undefined thì tôi đã giải thích ở trên ví dụ 1, về output thứ 2 là Hello there thì là do khi trình biên dịch chạy đến dòng code var a = "Hello there", khí đó variables a đã được gán cho giá trị là"Hello there" nên nó không còn là undefined nữa mà lúc này biến a đã có giá trị là"Hello there" vậy nên khiconsole.log(a) ở dòng thứ 3 được chạy thì ta có output là Hello there

3. Một vài lưu ý

  1. khi khai báo biến với từ khóa let hoặc const thì biến đó sẽ không được hoisting

4. Kết luận

Qua bài viết trên, tôi mong rằng các bạn sẽ có cái nhìn đúng và hiểu hơn về hoisting trong javascript.Chúc các bạn thành công trên con đường của mình


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí