Javascript: Ngữ cảnh thực thi(Execution Context)

Javascript: Ngữ cảnh thực thi(Execution Context)

Javascript là một trong những ngôn ngữ phổ biến nhất hiện nay. Nó có mặt cả client(Javascript) và cả server(Nodejs). Trong javascript ta có động cơ javascript( javascript engine), nó có nhiệm vụ thực thi code của chúng ta trên trình duyệt web. Nhưng đa số chúng ta không hiểu nó chạy thê nào khi ta nhúng một script vào web application.

Giải thích một số xíu về các thuật ngữ 🙂

Ngữ cảnh thực thi (Execution Context): Khi trang web ta chạy lên, nó sẽ mặc định tạo ra một Global Context là Window. Sau đó, nếu ta tạo một function thì mỗi function sẽ có một Execution Context nữa.
Phạm vi(scope, scope chain, lexical scope): Là một phạm vi hay nơi mà biến tồn tại và truy xuất được. Ra khỏi scope thì biến không còn nữa.

Hãy xem đoạn code sau nhé 🙂

function b() {
 var myVar = 3;
 console.log(myVar);// 3
}
function a() {
 var myVar = 2;
 b();
 console.log(myVar);// 2
}

var myVar = 1;
console.log(myVar);//1
a();
console.log(myVar);//1

Khi thực thi đoạn code trên, javascript sẽ tạo thành một Execution Stack như sau:

Global Context => function a Context => function b Context.

Global context sẽ tạo ra this và object Window, mà ở đây this cũng chính là object Window. Ta có thể hiểu context = scope. Nó tạo ra một phạm vi hay ngữ cảnh cho function. Nên nhớ var là function scope.
Javascript là một ngôn ngữ synchronous(đồng bộ) và single thread(đơn luồng). Code sẽ thực thi theo thứ tự line by line, top to bottom. Thứ từ thực thi sẽ là: function a thực thi, sau đó function b thực thi. Mỗi function đều có context của nó, nên sau khi thực thi Context cũng được xóa bỏ.

Thay đổi một tí đoạn code trên:

function b() {
 console.log(myVar);//1
}
function a() {
 var myVar = 2;
 b();
 console.log(myVar);// 2
}

var myVar = 1;
console.log(myVar);//1
a();

Function b sẽ in ra màn hình 1. Tại sao? Tai sao không phải là 2? Vì ta thấy function b được gọi trong context của a?
Mỗi một function đều tham chiếu tới outer environment(phạm vi tham chiếu) của nó. Ở đây function b có outer environment là Global Context và function a cũng có outer environment là Global context.

Thay đổi outer environment cho function b nhé 🙂

function a() {
 function b() {
 console.log(myVar);//2
 }
 var myVar = 2;
 b();
 console.log(myVar);// 2
}

var myVar = 1;
console.log(myVar);//1
a();

Function b sẽ in ra màn hình là 2 vì outer environment của nó là function a.
Một ví dụ khác nhé:

function a() {
 function b() {
 console.log(myVar);//1
 }
 b();
}

var myVar = 1;
console.log(myVar);//1
a();

Function b sẽ in ra gì? Có phải undefined? Không, nó in ra 1. Ở đây ta có scope chain như sau: function b có outer environment là a, a có outer environment là Global Context. Nên khi function b tìm biến myVar không có trong context chính nó, nó sẽ tìm tiếp lên outer environment của nó là function a, a cũng không có, tiêp tục tìm trên outer environment của a là Global Context thì myVar là 1.

Tóm lại, Execution Context chúng ta rất dễ bỏ qua, vì khi học javascript mọi người thường chỉ học bề nổi của nó, không tìm hiểu kỹ về phần nền tảng của nó . Hiểu được cái này, chúng ta dễ debug biết được những biến ảnh hưởng bởi những hàm nào, phạm vi nào ? Tại sao không thấy khai báo nhưng thực thi nó lại tồn tại và có giá trị? Vì scope chain trong javascript khá phức tạp. Nó thừa kế từ cha của cha của cha … và cha cuối cùng là Global Context. VAR có quá nhiều outer context làm chúng ta không biết khi nào hết phạm vi truy cập của nó. Đó cũng là một nguyên nhân var bị khai tử trong ES6.

2 thoughts on “Javascript: Ngữ cảnh thực thi(Execution Context)”

  1. Hello there,

    My name is Aly and I would like to know if you would have any interest to have your website here at thaunguyen.com promoted as a resource on our blog alychidesign.com ?

    We are in the midst of updating our broken link resources to include current and up to date resources for our readers. Our resource links are manually approved allowing us to mark a link as a do-follow link as well
    .
    If you may be interested please in being included as a resource on our blog, please let me know.

    Thanks,
    Aly

Leave a Comment