Nếu bạn đang hoặc muốn trở thành một nhà phát triển JavaScript, thì bạn phải biết cách các chương trình JavaScript được thực thi bên trong. Sự hiểu biết về bối cảnh thực thi và ngăn xếp thực thi là rất quan trọng để hiểu các khái niệm JavaScript khác như Nâng, Phạm vi và Đóng
Hiểu đúng khái niệm ngữ cảnh thực thi và ngăn xếp thực thi sẽ giúp bạn trở thành nhà phát triển JavaScript tốt hơn nhiều
Vì vậy, không cần phải quảng cáo thêm, hãy bắt đầu. ]
Mẹo. Sử dụng Bit để xây dựng ứng dụng JS nhanh hơn với các thành phần. Nó giúp bạn chia sẻ và tái sử dụng các thành phần với nhóm của mình, sử dụng chúng để xây dựng các ứng dụng mới. Hãy thử một lần
Hợp tác và khám phá thành phần · Bit
Bit là nơi các nhà phát triển chia sẻ các thành phần và hợp tác để cùng nhau xây dựng phần mềm tuyệt vời. Khám phá các thành phần được chia sẻ…
chút. nhà phát triển
Phản ứng spinners với Bit. Chọn, Chơi, Cài đặt
Bối cảnh thực thi là gì?
Nói một cách đơn giản, bối cảnh thực thi là một khái niệm trừu tượng về môi trường nơi mã Javascript được đánh giá và thực thi. Bất cứ khi nào bất kỳ mã nào được chạy trong JavaScript, nó sẽ chạy bên trong ngữ cảnh thực thi
Các loại bối cảnh thực hiện
Có ba loại ngữ cảnh thực thi trong JavaScript
- Bối cảnh thực thi toàn cầu — Đây là bối cảnh thực thi mặc định hoặc cơ sở. Mã không nằm trong bất kỳ chức năng nào nằm trong bối cảnh thực thi toàn cầu. Nó thực hiện hai điều. nó tạo một đối tượng toàn cầu là đối tượng cửa sổ [trong trường hợp trình duyệt] và đặt giá trị của
ExecutionContext = {
2 bằng với đối tượng toàn cầu. Chỉ có thể có một bối cảnh thực thi toàn cầu trong một chương trình
LexicalEnvironment = ,
VariableEnvironment = ,
} - Bối cảnh thực thi chức năng — Mỗi khi một chức năng được gọi, một bối cảnh thực thi hoàn toàn mới sẽ được tạo cho chức năng đó. Mỗi chức năng có bối cảnh thực thi riêng, nhưng nó được tạo khi chức năng được gọi hoặc gọi. Có thể có bất kỳ số lượng ngữ cảnh thực thi chức năng nào. Bất cứ khi nào một ngữ cảnh thực thi mới được tạo, nó sẽ trải qua một loạt các bước theo thứ tự xác định mà tôi sẽ thảo luận sau trong bài viết này
- Bối cảnh thực thi hàm đánh giá — Mã được thực thi bên trong một hàm
ExecutionContext = {
3 cũng có ngữ cảnh thực thi riêng, nhưng vì
LexicalEnvironment = ,
VariableEnvironment = ,
}ExecutionContext = {
3 thường không được các nhà phát triển JavaScript sử dụng nên tôi sẽ không thảo luận về nó ở đây
LexicalEnvironment = ,
VariableEnvironment = ,
}
Ngăn xếp thực thi, còn được gọi là “ngăn xếp cuộc gọi” trong các ngôn ngữ lập trình khác, là ngăn xếp có cấu trúc LIFO [Last in, First out], được sử dụng để lưu trữ tất cả bối cảnh thực thi được tạo trong quá trình thực thi mã
Khi công cụ JavaScript lần đầu tiên gặp tập lệnh của bạn, nó sẽ tạo ngữ cảnh thực thi toàn cầu và đẩy nó vào ngăn xếp thực thi hiện tại. Bất cứ khi nào công cụ tìm thấy một lệnh gọi hàm, nó sẽ tạo ngữ cảnh thực thi mới cho hàm đó và đẩy nó lên đầu ngăn xếp
Công cụ thực thi chức năng có bối cảnh thực thi ở trên cùng của ngăn xếp. Khi chức năng này hoàn thành, ngăn xếp thực thi của nó sẽ được bật ra khỏi ngăn xếp và điều khiển sẽ chuyển đến ngữ cảnh bên dưới nó trong ngăn xếp hiện tại
Hãy hiểu điều này với một ví dụ mã bên dưới
let a = 'Hello World!';function first[] {
console.log['Inside first function'];
second[];
console.log['Again inside first function'];
}function second[] {
console.log['Inside second function'];
}first[];
console.log['Inside Global Execution Context'];
Ngăn xếp ngữ cảnh thực thi cho đoạn mã trên
Khi đoạn mã trên tải trong trình duyệt, công cụ Javascript sẽ tạo ngữ cảnh thực thi toàn cầu và đẩy nó vào ngăn xếp thực thi hiện tại. Khi gặp lệnh gọi tới
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
5, công cụ Javascript sẽ tạo ngữ cảnh thực thi mới cho chức năng đó và đẩy nó lên đầu ngăn xếp thực thi hiện tạiKhi hàm
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
6 được gọi từ bên trong hàm ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
5, công cụ Javascript sẽ tạo ngữ cảnh thực thi mới cho hàm đó và đẩy nó lên đầu ngăn xếp thực thi hiện tại. Khi hàm ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
6 kết thúc, ngữ cảnh thực thi của nó sẽ được bật ra khỏi ngăn xếp hiện tại và điều khiển chuyển đến ngữ cảnh thực thi bên dưới nó, đó là ngữ cảnh thực thi hàm ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
5Khi
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
5 kết thúc, ngăn xếp thực thi của nó sẽ bị xóa khỏi ngăn xếp và quyền kiểm soát sẽ chuyển sang bối cảnh thực thi toàn cầu. Khi tất cả mã được thực thi, công cụ JavaScript sẽ xóa bối cảnh thực thi toàn cầu khỏi ngăn xếp hiện tạiBối cảnh thực thi được tạo ra như thế nào?Cho đến bây giờ, chúng ta đã thấy cách công cụ JavaScript quản lý ngữ cảnh thực thi, Bây giờ hãy hiểu cách một ngữ cảnh thực thi được tạo bởi công cụ JavaScript
Bối cảnh thực thi được tạo theo hai giai đoạn. 1] Giai đoạn tạo và 2] Giai đoạn thực hiện
Giai đoạn sáng tạoBối cảnh thực thi được tạo trong giai đoạn tạo. Những điều sau đây xảy ra trong giai đoạn tạo
- Thành phần LexicalEnvironment được tạo
- Thành phần VariableEnvironment được tạo
Vì vậy, bối cảnh thực thi có thể được biểu diễn theo khái niệm như sau
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
Môi trường từ vựng
Các tài liệu ES6 chính thức định nghĩa Lexical Environment là
Môi trường từ vựng là một loại đặc tả được sử dụng để xác định sự liên kết của Mã định danh với các biến và hàm cụ thể dựa trên cấu trúc lồng từ vựng của mã ECMAScript. Môi trường từ điển bao gồm một Bản ghi môi trường và một tham chiếu có thể null đến Môi trường từ điển bên ngoài
Nói một cách đơn giản, Môi trường từ vựng là một cấu trúc chứa ánh xạ biến định danh. [ở đây định danh đề cập đến tên của biến/hàm và biến là tham chiếu đến đối tượng thực [bao gồm đối tượng hàm và đối tượng mảng] hoặc giá trị nguyên thủy]
Ví dụ: xem xét đoạn mã sau
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
1Vì vậy, môi trường từ vựng cho đoạn mã trên trông như thế này
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
2Mỗi Lexical Environment có ba thành phần
- Bản ghi môi trường
- Tham chiếu đến môi trường bên ngoài,
- ràng buộc này
Bản ghi môi trường
Bản ghi môi trường là nơi lưu trữ các khai báo biến và hàm bên trong môi trường từ vựng
Ngoài ra còn có hai loại hồ sơ môi trường
- Bản ghi môi trường khai báo — Như tên gọi của nó, lưu trữ các khai báo hàm và biến. Môi trường từ vựng cho mã hàm chứa bản ghi môi trường khai báo
- Bản ghi môi trường đối tượng — Môi trường từ vựng cho mã toàn cầu chứa bản ghi môi trường khách quan. Ngoài các khai báo biến và hàm, bản ghi môi trường đối tượng còn lưu trữ một đối tượng liên kết toàn cầu [đối tượng cửa sổ trong trình duyệt]. Vì vậy, đối với mỗi thuộc tính của đối tượng ràng buộc [trong trường hợp trình duyệt, nó chứa các thuộc tính và phương thức do trình duyệt cung cấp cho đối tượng cửa sổ], một mục nhập mới được tạo trong bản ghi
Lưu ý — Đối với mã hàm, bản ghi môi trường cũng chứa một đối tượng
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
11 chứa ánh xạ giữa các chỉ mục và đối số được truyền cho hàm và độ dài [số] của các đối số được truyền vào hàm. Ví dụ: một đối tượng đối số cho hàm bên dưới trông như thế nàyExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
4Tham chiếu đến môi trường bên ngoài
Tham chiếu đến môi trường bên ngoài có nghĩa là nó có quyền truy cập vào môi trường từ vựng bên ngoài của nó. Điều đó có nghĩa là công cụ JavaScript có thể tìm kiếm các biến bên trong môi trường bên ngoài nếu chúng không được tìm thấy trong môi trường từ vựng hiện tại
Ràng buộc này
Trong thành phần này, giá trị của
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
2 được xác định hoặc đặtTrong bối cảnh thực thi toàn cầu, giá trị của
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
2 đề cập đến đối tượng toàn cầu. [trong trình duyệt, ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
2 đề cập đến Đối tượng Cửa sổ]Trong ngữ cảnh thực thi hàm, giá trị của
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
2 phụ thuộc vào cách gọi hàm. Nếu nó được gọi bởi một tham chiếu đối tượng, thì giá trị của ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
2 được đặt cho đối tượng đó, nếu không, giá trị của ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
2 được đặt cho đối tượng toàn cục hoặc ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
18 [ở chế độ nghiêm ngặt]. Ví dụExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
2Tóm lại, môi trường từ vựng trông như thế này trong mã giả
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
3Môi trường biến
Đó cũng là một Môi trường từ điển có Bản ghi môi trường chứa các ràng buộc được tạo bởi Biến báo cáo trong ngữ cảnh thực thi này
Như đã viết ở trên, môi trường biến cũng là môi trường từ vựng, nên nó có đầy đủ các thuộc tính và thành phần của môi trường từ vựng như đã định nghĩa ở trên
Trong ES6, một điểm khác biệt giữa thành phần LexicalEnvironment và thành phần VariableEnvironment là thành phần trước được sử dụng để lưu trữ khai báo hàm và các ràng buộc biến [
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
19 và ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
20], trong khi thành phần sau chỉ được sử dụng để lưu trữ các ràng buộc biến ____121Giai đoạn thực hiệnTrong giai đoạn này, việc gán cho tất cả các biến đó được thực hiện và mã cuối cùng được thực thi
Hãy xem xét một số ví dụ để hiểu các khái niệm trên
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
7Khi đoạn mã trên được thực thi, công cụ JavaScript sẽ tạo bối cảnh thực thi toàn cầu để thực thi mã toàn cầu. Vì vậy, bối cảnh thực thi toàn cầu sẽ giống như thế này trong giai đoạn tạo
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
8Trong giai đoạn thực thi, việc gán biến được thực hiện. Vì vậy, bối cảnh thực thi toàn cầu sẽ giống như thế này trong giai đoạn thực thi
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
9Khi gặp lệnh gọi hàm
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
22, ngữ cảnh thực thi hàm mới được tạo để thực thi mã hàm. Vì vậy, ngữ cảnh thực thi chức năng sẽ giống như thế này trong giai đoạn tạoExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
0Sau đó, bối cảnh thực thi sẽ trải qua giai đoạn thực thi, nghĩa là việc gán cho các biến bên trong hàm được thực hiện. Vì vậy, ngữ cảnh thực thi chức năng sẽ giống như thế này trong giai đoạn thực thi
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
1Sau khi chức năng hoàn thành, giá trị trả về được lưu trữ bên trong
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
23. Vì vậy, môi trường từ vựng toàn cầu được cập nhật. Sau đó, mã toàn cầu hoàn thành và chương trình kết thúcLưu ý — Như bạn có thể nhận thấy rằng các biến được xác định
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
19 và ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
20 không có bất kỳ giá trị nào được liên kết với chúng trong giai đoạn tạo, nhưng các biến được xác định ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
26 được đặt thành ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
18Điều này là do, trong giai đoạn tạo, mã được quét để tìm các khai báo hàm và biến, trong khi toàn bộ khai báo hàm được lưu trữ trong môi trường, các biến ban đầu được đặt thành
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
18 [trong trường hợp là ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
26] hoặc vẫn chưa được khởi tạo [trong trường hợp Đây là lý do tại sao bạn có thể truy cập các biến được xác định bởi
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
26 trước khi chúng được khai báo [mặc dù là ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
18] nhưng lại gặp lỗi tham chiếu khi truy cập các biến ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
19 và ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
20 trước khi chúng được khai báoĐây là, những gì chúng ta gọi cẩu
Lưu ý — Trong giai đoạn thực thi, nếu công cụ JavaScript không thể tìm thấy giá trị của biến
ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
19 tại vị trí thực tế mà nó được khai báo trong mã nguồn, thì nó sẽ gán cho biến đó giá trị là ExecutionContext = {
LexicalEnvironment = ,
VariableEnvironment = ,
}
18Phần kết luậnVì vậy, chúng tôi đã thảo luận về cách các chương trình JavaScript được thực thi bên trong. Mặc dù bạn không nhất thiết phải học tất cả các khái niệm này để trở thành một nhà phát triển JavaScript tuyệt vời, nhưng việc hiểu rõ các khái niệm trên sẽ giúp bạn hiểu các khái niệm khác như Hoisting, Scope và Closures dễ dàng và sâu sắc hơn
Vậy là xong và nếu bạn thấy bài viết này hữu ích, vui lòng nhấn nút 👏 và bình luận bên dưới. Rất vui được nói chuyện 😃
Được chia sẻ trong blog của Bit
Bit giúp dễ dàng chia sẻ các thành phần và mô-đun nhỏ giữa các dự án và ứng dụng để bạn và nhóm của bạn có thể xây dựng nhanh hơn. Chia sẻ các thành phần, phát triển chúng ở mọi nơi và tạo ra một bộ sưu tập tuyệt đẹp. Thử nó