Oke, một lần nữa, để hiểu mấy cái sau như Scope Chain thì việc hiểu Execution Stack đây rất quan trọng
Gọi hàm
Lập trình viên để mát hơn khi thuyết trình hay chém gió cần 'chêm' thấy từ tiếng Anh vô. Ví dụ lập trình hướng đối tượng ta sẽ nói là Ôu ô pi. Lớp ta sẽ đọc là flag lát sì, hàm ta sẽ gọi là phân hóa
Giỡn thui, chứ tại mấy ông pro hay đọc nhiều sách, xem nhiều video nên hay bị ngứa nên lâu lâu chụp tiếng Anh là bình thường
Quay lại vấn đề để gọi hàm [ chạy hàm ] tiếng Anh là ìn vâu kờ [ gọi ]
Ủ?
Được rồi, sau khi khai báo hàm, để chạy ta sử dụng 2 dấu [ ] sau tên của hàm đó, ví dụ
hàm a[]{ bảng điều khiển. nhật ký ['niviki. com'];
a[] // gọi hàm
Cái này dễ ẹt, ai biết không?
Sau này có mấy niệm dựa trên cái gọi hàm này nè, đừng có kinh nha, tới lúc đó tại sao không nhắc trước, tỉnh như đống này
Gọi hàm mà còn có kiểu function[][] như vậy ư, thấy cú pháp lạ chưa?
Thôi, quay lại bài học nào. Cho ví dụ sau, câu hỏi Bối cảnh thực thi được tạo như thế nào
function b[]{ var b } function a[]{ b[] // gọi hàm }
a[] // gọi hàm
Khi chạy, trước tiên Bối cảnh thực thi toàn cầu sẽ được tạo trước, tiếp theo là các Bối cảnh thực thi khác được tạo và bỏ vào ngăn xếp được gọi là Ngăn xếp thực thi
Tức là khi mỗi một hàm thực thi [ hàm gọi ] sẽ có một Bối cảnh thực thi được tạo ra và xếp vào một ngăn xếp
Khi hàm chạy xong, Execution Context chứa hàm đó sẽ được bật ra bên ngoài
Môi trường biến
Đoạn mã trên cũng vậy, ta thêm một chút
function b[]{ var myVar } function a[]{ b[] // gọi hàm var myVar = 69 }
var myVar = 0 a[] // gọi hàm
Khi Execution Context được tạo, nó sẽ chứa luôn các biến bên trong nó
Như ví dụ trên, myVar được khởi động 3 lần ở 3 Bối cảnh thực thi khác nhau, mỗi nơi có một giá trị khác nhau
Khi hàm chạy xong, Execution Context bị bật ra hết khỏi Ngăn xếp thực thi và chỉ còn lại 1 Global Execution Context. Vì thế giá trị của myVar sau khi chạy hàm a[] là 0
Hình minh họa
File file
văn bản var = 'bên ngoài'; . nhật ký [văn bản];
Kết quả ra là gì?
Kết quả
Thiệt ra cái này khi giải thích, mọi người cứ hay nói là phạm vi và người nghe vẫn hiểu đại ý là thư thế
Nhưng ý mình muốn các bạn hiểu rõ chi tiết, cách nó hoạt động bên trong. Có 2 lợi ích khi hiểu công việc này là
JavaScript
đã trở thành một trong những ngôn ngữ lập trình biến phổ biến nhất hiện nay. Nó cũng dẫn đầu về kho lưu trữ số lượng GitHub và là ngôn ngữ lập trình được thảo luận nhiều nhất trên StackOverflow
Do đó, điều rất quan trọng là bạn phải hiểu những điều cơ bản và biết điều gì xảy ra đằng sau bất kỳ chương trình JS nào và nó được thực thi như thế nào, nếu bạn muốn đi sâu vào JS
Bối cảnh thực thi [EC]
Mọi thứ trong JS đều xảy ra bên trong Execution Context
. Nó là môi trường mà mã JS được thực thi. Nó bao gồm giá trị của 'cái này', các biến, đối tượng và chức năng mà mã JS có quyền truy cập vào bất kỳ thời điểm cụ thể nào dưới dạng các cặp key-value
. Mỗi code block
sẽ có EC
riêng mà nó đang thực thi
Hãy nhìn vào phía trên, nó bao gồm hai phần
- Bộ nhớ [bộ nhớ]. Tất cả các biến có trong mã của bạn được lưu trữ ở đây dưới dạng các cặp
key-value
- Mã số. Đây là một luồng nơi mã được thực thi, một dòng tại một thời điểm
Các loại bối cảnh thực thi
- Bối cảnh thực thi toàn cầu [GEC]. Nó được tạo một lần cho mọi chương trình theo mặc định. Nó bao gồm mã không có bên trong bất kỳ chức năng [chức năng] nào. GEC chịu trách nhiệm chính về hai công việc
- nó tạo ra một đối tượng toàn cục [đối tượng toàn cục] là đối tượng cửa sổ [dành cho các trình duyệt]
- it set value of
this
byglobal object
GEC bị xóa sau khi quá trình thực thi toàn bộ chương trình kết thúc
- Bối cảnh thực thi chức năng [FEC]. Mỗi khi một hàm được gọi, ngữ cảnh thực thi sẽ được tạo cho hàm đó. Nó sẽ rõ ràng khi hàm trả về thứ đó hoặc quá trình thực thi của nó kết thúc
Bối cảnh thực thi được tạo như thế nào
JavaScript Engine tạo Execution Context
trong 2 giai đoạn
- Giai đoạn sáng tạo. ITrong giai đoạn này,
StackOverflow
0 chỉ quét toàn bộ mã nhưng không thực hiện nó. Nó tạo raStackOverflow
1 rồi cấp phát bộ nhớ cho mọi biến [với giá trị của nó làStackOverflow
2] và cácStackOverflow
3 trong phạm vi của nó. Sau đó, nó cũng khởi tạo giá trị củathis
- Giai đoạn thực hiện. Trong giai đoạn này, công cụ JS thực hiện quét lại mã để cập nhật các biến và hoàn tất quá trình thực thi
Bất kể khi nào bạn chạy mã JS của mình, trong StackOverflow
5, một StackOverflow
6 được tạo ra để lưu trữ tất cả các biến toàn cục có giá trị là StackOverflow
2 và các chức năng với phần thân của nó là giá trị. Sau đó, một EC duy nhất được tạo cho các chức năng khác hoạt động theo cùng một cách
- trước tiên nó lưu trữ và cấp phát bộ nhớ cho tất cả các biến cục bộ của hàm đó
- thực thi mã khối và tự hủy sau khi
StackOverflow
8 của nó kết thúc
Ví dụ
1
2
3
4
5
6
7
8
9
10