UnderstandJavaScript - The Excution Context : Creation and "Hoisting"

Trong những phần trước chúng tôi đã biết rằng JavascriptEngine (JSE) bao bọc code đang chạy của chúng ta trong Execution Context  nhưng có một khía cạnh quan trọng trong javascript mà chúng ta cần phải hiểu đó là Creation và Hoisting , để hiểu được điều này chúng ta cần hiểu rõ quá trình JSE tạo bối cảnh thực thi như thế nào ?

Hãy cùng xem một ví dụ :



Mở màn hình console lên bạn sẽ thấy :


Không có gì đáng nói ở đoạn code trên nhưng bạn sẽ thấy khi ta thay đổi vị trị các dòng code .


Kết quả sẽ cho ra như sau :


Trong hầu hết các ngôn ngữ lập trình bạn sẽ gặp lỗi bởi vì theo nguyên tắc chúng ta phải khai báo sau đó mới được sử dụng chúng nhưng JavaScript không như vậy , bạn có thể nhìn thấy ở trong hình mặc dù hàm được gọi sau đó mới khai báo nhưng nó vẫn chạy , biến a thì chương trình báo lỗi rằng chưa gán giá trị cho nó (underfine) (bạn chú ý nếu bạn không khai báo biến a thì console sẽ in ra như thế này )



Hiện tượng trên được gọi là Hoisting ,nhiều lập trình viên giải thích rằng Hoisting là hành vi di chuyển các biến (var) và các hàm (statement) lên đầu của hàm (scope của biến có thể là toàn cục hoặc cục bộ tùy theo cách nó được khai báo trong hàm nhưng nó luôn luôn được di chuyển lên đầu hàm - nơi mà nó được định nghĩa) như thể nó được di chuyển về mặt vật lý nhưng đây là quan niệm sai lầm.
 hãy để mình giải thích cho các bạn.
=> Có thể bạn giải thích điều này rằng các biến và các hàm trong Javascript được "cẩu" lên đầu bởi JSE nhưng bạn có thể thấy nói như vậy không hoàn toàn đúng vì biến a có được gán cho "Hello world" đâu...Khi bạn viết code như ảnh thứ 3 có thể dự đoán rằng chương trình hiểu nó như thế này :



Lý do Javascript chạy theo cách này là các biến và các hàm ở một mức độ nào đó có sẵn mặc dù chúng được khai báo sau trong code của bạn , đi vào chi tiết thì bạn có thể hiểu bởi vì Execution Context được tạo ra trong hai giai đoạn :

+ Giai đoạn đầu tiên được gọi là giai đoạn sáng tạo (creation phase) trong giai đoạn đó chúng ta biết rằng chúng ta có Global Object và This  được thiết lập trong bộ nhớ cùng với đó là Outer Environment được tạo ra , trong giai đoạn Creation Phase khi Sysntax Parser chạy qua code của bạn
và bắt đầu thiết lập những gì bạn đã viết để dịch , nó nhận ra nơi bạn đã tạo ra biến và nơi bạn tạo ra hàm từ đó nó thiết lập bộ nhớ dành cho các biến và hàm => hiện tượng này được gọi là Hoisting .Nó không thực sự di chuyển các dòng mã khai báo lên đầu chương trình mà nó chỉ thiết lập trong vùng nhớ mà thôi. . Tổng kết lại rằng : Trước khi code của bạn bắt đầu được thực thi theo từng dòng thì JSE đã thiết lập không gian bộ nhớ để lưu trữ các biến và các hàm (biến khai báo kiểu var và hàm kiểu decleration thôi nhé.) bạn đã tạo trong toàn bộ code mà bạn viết ra.


- Từ đó các hàm và các biến đó tồn tại trong bộ nhớ . khi mã bắt đầu thực thi từng dòng nó có thể truy cập chúng tuy nhiên chúng ta cần phải chú ý vài điều khi nói đến các biến.

=> Đối với hàm thì tên của nó , code bên trong JSE lấy toàn bộ vào nhét vào trong bộ nhớ.
Nhưng đối với biến thì lại là câu truyện khác khi JSE thiết lập không gian trong bộ nhớ cho biến a nó chẳng biết giá trị cuối cùng của a là gì cho đến khi nó bắt đầu thực thi => Vì vậy thay vào đó , nó tự động thiết lập một giá trị cho a = underfine như kiểu JSE nói rằng "Ở giai đoạn 1 tao éo biết cái biến của nợ này có giá trị bằng bao nhiêu nên tạm thời gán cho nó = underfine " khi  sang giai đoạn 2 thực thi code thì tao sẽ gán giá trị cho nó sau.

=> Như vậy nói đây là hiện tượng "Hoisting" về mặt ngữ cảnh thì nó cũng không đúng lắm ^^.
Thực tế những gì bạn viết ra , chương trình bạn viết ra nó sẽ không được thực thi trực tiếp (bởi CPU) mà JSE lấy code của bạn và làm nhưng công việc như Tạo Execution Context để bao bọc khối code => Thiết lập bộ nhớ cho các biến và hàm đã khai báo để nó có thể sử dụng khi nó bắt đầu thực thi code.

Tuy nhiên giai đoạn tiếp theo , giai đoạn thực hiện (Code Execution) , nó sẽ thực thi từng dòng code của bạn.

Từ khóa 'This'


- This trỏ đến đối tượng gọi hàm chứa nó.
- This giúp gọi hàm với các bối cảnh khác nhau.
- Sử dụng Bind, Apply, Call xác định bối cảnh của từ khóa this (hay đối tượng mà this trỏ đến).


Nhận xét

Bài đăng phổ biến