Javascript Hoisting
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