Hướng dẫn how to check javascript flow of execution - cách kiểm tra luồng thực thi javascript

Có một trang web trên đó một khóa đặc biệt được tạo dựa trên dữ liệu trên trang nguồn. Tôi có thể bằng cách nào đó "từng bước" xem quy trình thực thi mã JavaScript trên trang web này để tìm khóa khóa này được tạo ở đâu không? Tôi có nghĩa là với khả năng theo dõi tất cả các biến cục bộ / toàn cầu được tạo và thay đổi trong quá trình thực thi mã.

P.S. Khóa này không được lưu trữ ở bất cứ đâu, nó được tạo trong mã JavaScript, với khóa này có kết nối nền với ổ cắm web và sau đó khóa này không được sử dụng ở bất kỳ nơi nào khác.

Khi được hỏi ngày 25 tháng 5 năm 2020 lúc 18:49May 25, 2020 at 18:49

Hướng dẫn how to check javascript flow of execution - cách kiểm tra luồng thực thi javascript

1

Hướng dẫn how to check javascript flow of execution - cách kiểm tra luồng thực thi javascript

Tất cả mã JavaScript cần được lưu trữ và chạy trong một số loại môi trường. Trong hầu hết các trường hợp, môi trường đó sẽ là một trình duyệt web.

Đối với bất kỳ đoạn mã JavaScript nào được thực thi trong trình duyệt web, rất nhiều quy trình diễn ra phía sau hậu trường. Trong bài viết này, chúng ta sẽ xem xét mọi thứ xảy ra đằng sau hậu trường để mã JavaScript chạy trong trình duyệt web.

Trước khi chúng ta đi sâu, đây là một số điều kiện tiên quyết để làm quen với bản thân, bởi vì chúng ta sẽ sử dụng chúng thường xuyên trong bài viết này.

  • Trình phân tích cú pháp: Trình phân tích cú pháp hoặc trình phân tích cú pháp cú pháp là một chương trình đọc từng dòng mã của bạn. Nó hiểu cách mã phù hợp với cú pháp được xác định bởi ngôn ngữ lập trình và những gì nó (mã) dự kiến ​​sẽ làm.: A Parser or Syntax Parser is a program that reads your code line-by-line. It understands how the code fits the syntax defined by the Programming Language and what it (the code) is expected to do.
  • Công cụ JavaScript: Công cụ JavaScript chỉ đơn giản là một chương trình máy tính nhận mã nguồn JavaScript và biên dịch nó với hướng dẫn nhị phân (mã máy) mà CPU có thể hiểu. Các công cụ JavaScript thường được phát triển bởi các nhà cung cấp trình duyệt web và mỗi trình duyệt chính có một. Các ví dụ bao gồm động cơ V8 cho Google Chrome, Spidermonkey cho Firefox và Chakra cho Internet Explorer.: A JavaScript engine is simply a computer program that receives JavaScript source code and compiles it to the binary instructions (machine code) that a CPU can understand. JavaScript engines are typically developed by web browser vendors, and each major browser has one. Examples include the V8 engine for Google chrome, SpiderMonkey for Firefox, and Chakra for Internet Explorer.
  • Tuyên bố chức năng: Đây là các chức năng được gán một tên.: These are functions that are assigned a name.
function doSomething() { //here "doSomething" is the function's name
statements; 
} 
  • Biểu thức chức năng: Đây là các hàm ẩn danh, đó là các hàm không có tên hàm như js function () { statements }. Chúng thường được sử dụng trong các câu lệnh, như gán một hàm cho một biến. ________số 8.: These are anonymous functions, that is functions without a function name like js function () { statements }. They are usually used in statements, like assigning a function to a variable. let someValue = function () { statements }.

Bây giờ, rằng chúng tôi đã tránh xa những thứ đó, chúng ta hãy lao vào.

Cách mã JavaScript được thực thi

Vì những người không biết, trình duyệt không hiểu mã JavaScript cấp cao mà chúng tôi viết trong các ứng dụng của chúng tôi. Nó cần được chuyển đổi thành một định dạng mà trình duyệt và máy tính của chúng tôi có thể hiểu - mã máy.

Trong khi đọc qua HTML, nếu trình duyệt gặp mã JavaScript để chạy qua thẻ

Bây giờ chúng ta nhận thức được bối cảnh thực thi là gì và các loại khác nhau có sẵn, chúng ta hãy xem xét cách tạo ra.

  1. Việc tạo ra một bối cảnh thực thi (GEC hoặc FEC) xảy ra theo hai giai đoạn:
  2. Giai đoạn sáng tạo
  3. Giai đoạn thực hiện

Trong giai đoạn sáng tạo, bối cảnh thực thi đầu tiên được liên kết với đối tượng bối cảnh thực thi (ECO). Đối tượng bối cảnh thực thi lưu trữ rất nhiều dữ liệu quan trọng mà mã trong bối cảnh thực thi sử dụng trong thời gian chạy của nó.

Giai đoạn tạo xảy ra trong 3 giai đoạn, trong đó các thuộc tính của đối tượng bối cảnh thực thi được xác định và đặt. Các giai đoạn này là:

Tạo đối tượng biến (VO)

Tạo chuỗi phạm vi

Đặt giá trị của từ khóa

getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
3

Hãy để chúng tôi đi qua từng giai đoạn chi tiết.

Giai đoạn tạo: Tạo đối tượng biến (VO)Hoisting. Since this is an important concept, we'll talk about it briefly before moving on to the next stage.

Đối tượng biến (VO) là một thùng chứa giống như đối tượng được tạo trong bối cảnh thực thi. Nó lưu trữ các biến và khai báo chức năng được xác định trong bối cảnh thực thi đó.

Trong GEC, đối với mỗi biến được khai báo với từ khóa

getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
4, một thuộc tính được thêm vào VO chỉ vào biến đó và được đặt thành 'không xác định'.

Chức năng nâng cao

Trong hầu hết các kịch bản khi xây dựng một ứng dụng, các nhà phát triển có thể chọn xác định các chức năng ở đầu tập lệnh và chỉ sau đó gọi chúng xuống mã, như vậy:

Hướng dẫn how to check javascript flow of execution - cách kiểm tra luồng thực thi javascript

Tuy nhiên, do nâng cao, điều ngược lại vẫn sẽ hoạt động. Trường hợp chúng ta có thể gọi các chức năng đầu tiên sau đó xác định chúng sau đó xuống tập lệnh.

Hướng dẫn how to check javascript flow of execution - cách kiểm tra luồng thực thi javascript

Trong mã trên, khai báo hàm

getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
5 sẽ được lưu trữ trong bộ nhớ của VO, làm cho nó có sẵn để sử dụng ngay cả trước khi nó được xác định.

Tăng cường biến

Các biến được khởi tạo với từ khóa

getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
4 được lưu trữ trong bộ nhớ của Vo cảnh thực hiện hiện tại là một thuộc tính và được khởi tạo với giá trị
getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
7. Điều này có nghĩa là, không giống như các chức năng, cố gắng truy cập giá trị của biến trước khi nó được xác định sẽ dẫn đến
getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
7.

Hướng dẫn how to check javascript flow of execution - cách kiểm tra luồng thực thi javascript

Quy tắc nâng cơ sở nâng

Tăng chỉ hoạt động cho các khai báo chức năng, không biểu thức. Dưới đây là một ví dụ về biểu thức chức năng trong đó thực thi mã sẽ bị phá vỡ.

getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};

Việc thực thi mã bị phá vỡ, bởi vì với các biểu thức chức năng,

getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
5 sẽ được nâng như một biến không phải là một hàm. Và với việc nâng biến biến, giá trị của nó sẽ được đặt thành
getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
7. Đó là lý do tại sao chúng tôi gặp lỗi:

Hướng dẫn how to check javascript flow of execution - cách kiểm tra luồng thực thi javascript

Ngoài ra, việc nâng biến không hoạt động cho các biến được khởi tạo với từ khóa

var occupation = "Frontend Developer"; 

function addOne(x) { 
    console.log(x + 1) 
}
1 hoặc
var occupation = "Frontend Developer"; 

function addOne(x) { 
    console.log(x + 1) 
}
2. Cố gắng truy cập một biến trước khai báo và sử dụng các từ khóa
var occupation = "Frontend Developer"; 

function addOne(x) { 
    console.log(x + 1) 
}
1 và
var occupation = "Frontend Developer"; 

function addOne(x) { 
    console.log(x + 1) 
}
2 để khai báo sau này sẽ dẫn đến
var occupation = "Frontend Developer"; 

function addOne(x) { 
    console.log(x + 1) 
}
5.

Trong trường hợp này, chúng sẽ được nâng lên nhưng không được gán với giá trị mặc định là

getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
7.
var occupation = "Frontend Developer"; 

function addOne(x) { 
    console.log(x + 1) 
}
7 sẽ ném lỗi:

Hướng dẫn how to check javascript flow of execution - cách kiểm tra luồng thực thi javascript

Giai đoạn sáng tạo: Tạo chuỗi phạm vi

Sau khi tạo ra đối tượng biến (VO), việc tạo ra chuỗi phạm vi là giai đoạn tiếp theo trong giai đoạn sáng tạo của bối cảnh thực hiện.

Phạm vi trong JavaScript là một cơ chế xác định mức độ có thể truy cập của một đoạn mã với các phần khác của cơ sở mã. Phạm vi trả lời các câu hỏi: Từ đâu có thể truy cập một đoạn mã? Nó không thể truy cập từ đâu? Điều gì có thể truy cập nó, và những gì không thể?

Mỗi bối cảnh thực thi chức năng tạo phạm vi của nó: không gian/môi trường nơi các biến và hàm mà nó xác định có thể được truy cập thông qua một quy trình gọi là phạm vi.

Điều này có nghĩa là vị trí của một cái gì đó trong một cơ sở mã, nghĩa là, nơi có một đoạn mã.

Khi một hàm được xác định trong một hàm khác, hàm bên trong có quyền truy cập vào mã được xác định theo hàm bên ngoài và của cha mẹ. Hành vi này được gọi là phạm vi từ vựng.lexical scoping.

Tuy nhiên, hàm bên ngoài không có quyền truy cập vào mã trong hàm bên trong.

Khái niệm về phạm vi này mang đến một hiện tượng liên kết trong JavaScript gọi là đóng cửa. Đây là khi các hàm bên trong luôn có quyền truy cập vào mã được liên kết với các hàm bên ngoài, ngay cả sau khi thực hiện các hàm bên ngoài hoàn tất. Bạn có thể tìm hiểu thêm đóng cửa ở đây.

Hãy xem xét một số ví dụ để hiểu rõ hơn:

Hướng dẫn how to check javascript flow of execution - cách kiểm tra luồng thực thi javascript
  • Bên phải là phạm vi toàn cầu. Đây là phạm vi mặc định được tạo khi tập lệnh
    var occupation = "Frontend Developer"; 
    
    function addOne(x) { 
        console.log(x + 1) 
    }
    8 được tải và có thể truy cập từ tất cả các chức năng trong suốt mã.
  • Hộp màu đỏ là phạm vi của hàm
    var occupation = "Frontend Developer"; 
    
    function addOne(x) { 
        console.log(x + 1) 
    }
    9, xác định biến
    window.occupation = "Frontend Developer"; 
    window.addOne = (x) => { 
    console.log(x + 1)
    };
    0 và hàm
    window.occupation = "Frontend Developer"; 
    window.addOne = (x) => { 
    console.log(x + 1)
    };
    1.
Hướng dẫn how to check javascript flow of execution - cách kiểm tra luồng thực thi javascript
  • Trong màu xanh lá cây là phạm vi của hàm
    window.occupation = "Frontend Developer"; 
    window.addOne = (x) => { 
    console.log(x + 1)
    };
    1. Có một câu lệnh
    window.occupation = "Frontend Developer"; 
    window.addOne = (x) => { 
    console.log(x + 1)
    };
    3 là in các biến
    window.occupation = "Frontend Developer"; 
    window.addOne = (x) => { 
    console.log(x + 1)
    };
    4,
    window.occupation = "Frontend Developer"; 
    window.addOne = (x) => { 
    console.log(x + 1)
    };
    5 và
    window.occupation = "Frontend Developer"; 
    window.addOne = (x) => { 
    console.log(x + 1)
    };
    6.

Bây giờ các biến

window.occupation = "Frontend Developer"; 
window.addOne = (x) => { 
console.log(x + 1)
};
4 và
window.occupation = "Frontend Developer"; 
window.addOne = (x) => { 
console.log(x + 1)
};
5 không được xác định trong hàm
window.occupation = "Frontend Developer"; 
window.addOne = (x) => { 
console.log(x + 1)
};
1, chỉ
window.occupation = "Frontend Developer"; 
window.addOne = (x) => { 
console.log(x + 1)
};
6. Tuy nhiên, do phạm vi từ vựng, nó có quyền truy cập vào phạm vi của hàm mà nó nằm trong và của cha mẹ của nó.

Khi chạy mã, động cơ JS sẽ không tìm thấy biến

window.occupation = "Frontend Developer"; 
window.addOne = (x) => { 
console.log(x + 1)
};
5 trong phạm vi của hàm
window.occupation = "Frontend Developer"; 
window.addOne = (x) => { 
console.log(x + 1)
};
1. Vì vậy, nó nhìn lên phạm vi của cha mẹ, bắt đầu với chức năng ____29. Ở đó, nó tìm thấy biến
var msg = "I will rule the world!"; 

function printMsg() { 
    console.log(this.msg); 
} 

printMsg(); // logs "I will rule the world!" to the console.
4. Nó quay trở lại hàm
window.occupation = "Frontend Developer"; 
window.addOne = (x) => { 
console.log(x + 1)
};
1 và giải quyết biến
window.occupation = "Frontend Developer"; 
window.addOne = (x) => { 
console.log(x + 1)
};
5 ở đó với nó.

Quá trình tương tự cho biến

window.occupation = "Frontend Developer"; 
window.addOne = (x) => { 
console.log(x + 1)
};
4. Động cơ JS nhìn lên qua phạm vi của tất cả cha mẹ của nó cho đến phạm vi của GEC, giải quyết giá trị của nó trong hàm
window.occupation = "Frontend Developer"; 
window.addOne = (x) => { 
console.log(x + 1)
};
1.

Ý tưởng này về động cơ JavaScript vượt qua phạm vi của bối cảnh thực thi mà một hàm được định nghĩa để giải quyết các biến và hàm được gọi trong chúng được gọi là chuỗi phạm vi.scope chain.

Hướng dẫn how to check javascript flow of execution - cách kiểm tra luồng thực thi javascript

Chỉ khi công cụ JS không thể giải quyết một biến trong chuỗi phạm vi, nó mới ngừng thực thi và ném lỗi.

Tuy nhiên, điều này không hoạt động lạc hậu. Đó là, phạm vi toàn cầu sẽ không bao giờ có quyền truy cập vào các biến của hàm bên trong trừ khi chúng là

var msg = "I will rule the world!"; 

function printMsg() { 
    console.log(this.msg); 
} 

printMsg(); // logs "I will rule the world!" to the console.
9 từ hàm.

Chuỗi phạm vi hoạt động như một kính một chiều. Bạn có thể nhìn thấy bên ngoài, nhưng mọi người từ bên ngoài không thể nhìn thấy bạn.

Và đó là lý do tại sao mũi tên màu đỏ trong hình trên là hướng lên trên bởi vì đó là hướng duy nhất mà chuỗi phạm vi đi.

Giai đoạn tạo: Đặt giá trị của từ khóa "này"

Giai đoạn tiếp theo và cuối cùng sau khi phạm vi trong giai đoạn tạo của bối cảnh thực thi đang đặt giá trị của từ khóa

getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
3.

Từ khóa JavaScript

getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
3 đề cập đến phạm vi nơi bối cảnh thực thi thuộc về.

Khi chuỗi phạm vi được tạo, giá trị của

var msg = "I will rule the world!"; 
const Victor = {
    msg: "Victor will rule the world!", 
    printMsg() { console.log(this.msg) }, 
}; 

Victor.printMsg(); // logs "Victor will rule the world!" to the console.
2 được khởi tạo bởi động cơ JS.

var msg = "I will rule the world!"; 
const Victor = {
    msg: "Victor will rule the world!", 
    printMsg() { console.log(this.msg) }, 
}; 

Victor.printMsg(); // logs "Victor will rule the world!" to the console.
3 trong bối cảnh toàn cầu

Trong GEC (bên ngoài bất kỳ chức năng và đối tượng nào),

getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
3 đề cập đến đối tượng toàn cầu - đó là đối tượng
var msg = "I will rule the world!"; 
const Victor = {
    msg: "Victor will rule the world!", 
    printMsg() { console.log(this.msg) }, 
}; 

Victor.printMsg(); // logs "Victor will rule the world!" to the console.
5.

Do đó, các khai báo chức năng và các biến được khởi tạo với từ khóa

getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
4 được gán dưới dạng thuộc tính và phương thức cho đối tượng toàn cầu - đối tượng
var msg = "I will rule the world!"; 
const Victor = {
    msg: "Victor will rule the world!", 
    printMsg() { console.log(this.msg) }, 
}; 

Victor.printMsg(); // logs "Victor will rule the world!" to the console.
5.

Điều này có nghĩa là việc khai báo các biến và chức năng bên ngoài bất kỳ chức năng nào, như thế này:

var occupation = "Frontend Developer"; 

function addOne(x) { 
    console.log(x + 1) 
}

Giống hệt như:

window.occupation = "Frontend Developer"; 
window.addOne = (x) => { 
console.log(x + 1)
};

Các chức năng và biến trong GEC được đính kèm dưới dạng các phương thức và thuộc tính cho đối tượng cửa sổ. Đó là lý do tại sao đoạn trích bên dưới sẽ trả về đúng.

Hướng dẫn how to check javascript flow of execution - cách kiểm tra luồng thực thi javascript
var msg = "I will rule the world!"; 
const Victor = {
    msg: "Victor will rule the world!", 
    printMsg() { console.log(this.msg) }, 
}; 

Victor.printMsg(); // logs "Victor will rule the world!" to the console.
3 trong các chức năng

Trong trường hợp của FEC, nó không tạo đối tượng

getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
3. Thay vào đó, nó có quyền truy cập vào môi trường mà nó được xác định.

Đây sẽ là đối tượng

var msg = "I will rule the world!"; 
const Victor = {
    msg: "Victor will rule the world!", 
    printMsg() { console.log(this.msg) }, 
}; 

Victor.printMsg(); // logs "Victor will rule the world!" to the console.
5, vì hàm được xác định trong GEC:

var msg = "I will rule the world!"; 

function printMsg() { 
    console.log(this.msg); 
} 

printMsg(); // logs "I will rule the world!" to the console.

Trong các đối tượng, từ khóa

getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
3 không trỏ đến GEC, mà là chính đối tượng. Tham khảo
getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
3 trong một đối tượng sẽ giống như:

var name = "Victor";

function first() {
  var a = "Hi!";
  second();
  console.log(`${a} ${name}`);
}

function second() {
  var b = "Hey!";
  third();
  console.log(`${b} ${name}`);
}

function third() {
  var c = "Hello!";
  console.log(`${c} ${name}`);
}

first();
3

Xem xét ví dụ mã dưới đây:

var msg = "I will rule the world!"; 
const Victor = {
    msg: "Victor will rule the world!", 
    printMsg() { console.log(this.msg) }, 
}; 

Victor.printMsg(); // logs "Victor will rule the world!" to the console.

Mã nhật ký

var name = "Victor";

function first() {
  var a = "Hi!";
  second();
  console.log(`${a} ${name}`);
}

function second() {
  var b = "Hey!";
  third();
  console.log(`${b} ${name}`);
}

function third() {
  var c = "Hello!";
  console.log(`${c} ${name}`);
}

first();
4 vào bảng điều khiển chứ không phải
var name = "Victor";

function first() {
  var a = "Hi!";
  second();
  console.log(`${a} ${name}`);
}

function second() {
  var b = "Hey!";
  third();
  console.log(`${b} ${name}`);
}

function third() {
  var c = "Hello!";
  console.log(`${c} ${name}`);
}

first();
5 bởi vì trong trường hợp này, giá trị của từ khóa
getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
3, hàm có quyền truy cập là của đối tượng được xác định, không phải đối tượng toàn cầu.

Với giá trị của bộ từ khóa

getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
3, tất cả các thuộc tính của đối tượng bối cảnh thực thi đã được xác định. Dẫn đến cuối giai đoạn sáng tạo, bây giờ động cơ JS chuyển sang giai đoạn thực hiện.

Giai đoạn thực thi

Cuối cùng, ngay sau giai đoạn sáng tạo của bối cảnh thực hiện xuất hiện trong giai đoạn thực thi. Đây là giai đoạn thực thi mã thực tế bắt đầu.

Cho đến thời điểm này, VO chứa các biến với các giá trị của

getAge(1990); 
var getAge = function (yearOfBirth) {
console.log(new Date().getFullYear - yearOfBirth) 
};
7. Nếu mã được chạy vào thời điểm này, nó bị ràng buộc trả về các lỗi, vì chúng ta không thể làm việc với các giá trị không xác định.

Ở giai đoạn này, công cụ JavaScript đọc mã trong bối cảnh thực thi hiện tại một lần nữa, sau đó cập nhật VO với các giá trị thực của các biến này. Sau đó, mã được phân tích cú pháp bởi trình phân tích cú pháp, được chuyển sang mã byte có thể thực thi và cuối cùng được thực thi.

Ngăn xếp thực thi, còn được gọi là ngăn xếp cuộc gọi, theo dõi tất cả các bối cảnh thực thi được tạo ra trong vòng đời của một tập lệnh.Call Stack, keeps track of all the Execution Contexts created during the life cycle of a script.

JavaScript là ngôn ngữ đơn luồng, điều đó có nghĩa là nó chỉ có khả năng thực hiện một nhiệm vụ tại một thời điểm. Do đó, khi các hành động, chức năng và sự kiện khác xảy ra, bối cảnh thực hiện được tạo cho mỗi sự kiện này. Do tính chất duy nhất của JavaScript, một loạt các bối cảnh thực thi chồng chất sẽ được thực thi được tạo ra, được gọi là

var name = "Victor";

function first() {
  var a = "Hi!";
  second();
  console.log(`${a} ${name}`);
}

function second() {
  var b = "Hey!";
  third();
  console.log(`${b} ${name}`);
}

function third() {
  var c = "Hello!";
  console.log(`${c} ${name}`);
}

first();
9.

Khi các tập lệnh tải trong trình duyệt, bối cảnh toàn cầu được tạo dưới dạng bối cảnh mặc định nơi công cụ JS bắt đầu thực thi mã và được đặt ở dưới cùng của ngăn xếp thực thi.

Động cơ JS sau đó tìm kiếm các cuộc gọi chức năng trong mã. Đối với mỗi cuộc gọi chức năng, một FEC mới được tạo cho chức năng đó và được đặt trên đầu bối cảnh thực thi hiện đang thực hiện.

Bối cảnh thực thi ở đầu ngăn xếp thực thi trở thành bối cảnh thực thi đang hoạt động và sẽ luôn được thực hiện trước tiên bởi động cơ JS.

Ngay khi việc thực thi tất cả các mã trong bối cảnh thực thi đang hoạt động được thực hiện, động cơ JS sẽ bật ra bối cảnh thực thi chức năng cụ thể đó của ngăn xếp thực thi, di chuyển về phía bên dưới nó, v.v.

Để hiểu quá trình làm việc của ngăn xếp thực thi, hãy xem xét ví dụ mã bên dưới:

var name = "Victor";

function first() {
  var a = "Hi!";
  second();
  console.log(`${a} ${name}`);
}

function second() {
  var b = "Hey!";
  third();
  console.log(`${b} ${name}`);
}

function third() {
  var c = "Hello!";
  console.log(`${c} ${name}`);
}

first();

Đầu tiên, tập lệnh được tải vào động cơ JS.

Sau đó, động cơ JS tạo ra GEC và đặt nó vào cơ sở của ngăn xếp thực hiện.

Hướng dẫn how to check javascript flow of execution - cách kiểm tra luồng thực thi javascript

Biến js function () { statements }0 được xác định bên ngoài bất kỳ chức năng nào, vì vậy nó nằm trong GEC và được lưu trữ trong nó là VO.

Quá trình tương tự xảy ra đối với các hàm

var occupation = "Frontend Developer"; 

function addOne(x) { 
    console.log(x + 1) 
}
9,
window.occupation = "Frontend Developer"; 
window.addOne = (x) => { 
console.log(x + 1)
};
1 và js function () { statements }3.

Đừng nhầm lẫn về lý do tại sao chúng hoạt động vẫn còn trong GEC. Hãy nhớ rằng, GEC chỉ dành cho mã JavaScript (biến và hàm) không nằm trong bất kỳ chức năng nào. Bởi vì chúng không được xác định trong bất kỳ chức năng nào, các khai báo chức năng nằm trong GEC. Có ý nghĩa bây giờ 😃?not inside of any function. Because they were not defined within any function, the function declarations are in the GEC. Make sense now 😃?

Khi động cơ JS bắt gặp cuộc gọi chức năng

var occupation = "Frontend Developer"; 

function addOne(x) { 
    console.log(x + 1) 
}
9, một FEC mới được tạo cho nó. Bối cảnh mới này được đặt trên đỉnh của bối cảnh hiện tại, hình thành cái gọi là
var name = "Victor";

function first() {
  var a = "Hi!";
  second();
  console.log(`${a} ${name}`);
}

function second() {
  var b = "Hey!";
  third();
  console.log(`${b} ${name}`);
}

function third() {
  var c = "Hello!";
  console.log(`${c} ${name}`);
}

first();
9.

Hướng dẫn how to check javascript flow of execution - cách kiểm tra luồng thực thi javascript

Trong suốt thời gian của cuộc gọi chức năng

var occupation = "Frontend Developer"; 

function addOne(x) { 
    console.log(x + 1) 
}
9, bối cảnh thực thi của nó trở thành bối cảnh hoạt động trong đó mã JavaScript được thực thi lần đầu tiên.

Trong hàm

var occupation = "Frontend Developer"; 

function addOne(x) { 
    console.log(x + 1) 
}
9, biến js function () { statements }8 được lưu trữ trong FEC của nó, không phải trong GEC.

Tiếp theo, hàm

window.occupation = "Frontend Developer"; 
window.addOne = (x) => { 
console.log(x + 1)
};
1 được gọi trong hàm
var occupation = "Frontend Developer"; 

function addOne(x) { 
    console.log(x + 1) 
}
9.

Việc thực hiện hàm

var occupation = "Frontend Developer"; 

function addOne(x) { 
    console.log(x + 1) 
}
9 sẽ được tạm dừng do tính chất đơn của JavaScript. Nó phải đợi cho đến khi thực hiện nó, đó là hàm
window.occupation = "Frontend Developer"; 
window.addOne = (x) => { 
console.log(x + 1)
};
1, đã hoàn tất.

Một lần nữa, động cơ JS thiết lập một FEC mới cho chức năng

window.occupation = "Frontend Developer"; 
window.addOne = (x) => { 
console.log(x + 1)
};
1 và đặt nó ở đầu ngăn xếp, làm cho nó trở thành bối cảnh hoạt động.

Hướng dẫn how to check javascript flow of execution - cách kiểm tra luồng thực thi javascript

Hàm

window.occupation = "Frontend Developer"; 
window.addOne = (x) => { 
console.log(x + 1)
};
1 trở thành bối cảnh hoạt động, biến let someValue = function () { statements }5 được lưu trữ trong FEC của nó và hàm js function () { statements }3 được gọi trong hàm
window.occupation = "Frontend Developer"; 
window.addOne = (x) => { 
console.log(x + 1)
};
1. FEC của nó được tạo ra và đặt trên đầu của ngăn xếp thực thi.

Hướng dẫn how to check javascript flow of execution - cách kiểm tra luồng thực thi javascript

Bên trong hàm js function () { statements }3, biến let someValue = function () { statements }9 được lưu trữ trong FEC của nó và thông báo