Học Javascript 6: Scope Chain là gì?
Giới thiệu
Ở bài trước Execution Stack là gì?, mình có để đoạn code sau:
var text = 'outside'; function show(){ console.log(text); var text = 'inside'; }; show();
Có một bạn vào trả lời như sau:
Hiểu theo cách này cũng được. Nhưng trong 5 bài học trước từ Lexical Environment, Global Environment, hoisting và Execution Stack, mình muốn các bạn hiểu rõ tại sao kết quả code chạy như vậy, chứ không phải hiểu theo cảm tính ( vì trước đây mình cũng từng nghĩ như vậy ). Hay giải thích kiểu vu vơ như tại Scope nó như vậy.
Và hôm nay, chúng ta sẽ tập trung vào đoan code này
function b() { console.log(text); }
function a() { var text = "in a"; b(); }
a(); var text = "in gloal";
Theo bạn, kết quả in ra là gì, giải thích tại sao?
Nếu bạn có theo dõi các bài trước, thì có thể vẽ được Execution Stack như thế này:
Có thể bạn đang nghĩ vì không có biến text trong hàm b() nên có thể chương trình báo lỗi.
Outer Environment
Ở bài Global Environment và Global Object, mình có nhắc qua về Outer Environment, vậy nó là gì? Outer Environment của một Execution Context sẽ trỏ tới một Execution Context khác 'bao' bên ngoài gần nó nhất ( hay ám chỉ Lexical Environment của Execution Context đó )
Khó hiểu lúng đúng không? Mình cũng thấy vậy, thiệt ra định nghĩa dài dòng vậy thôi chứ nó đơn giản lắm.
Giống ví dụ trên Outer Environment của hàm cả hàm a() và b() đều là global
Scope Chain là gì?
Quay lại đoạn code trên, kết quả sẽ là undefined.
Vì trong một Execution Context, nếu ta truy cập giá trị một biến, mà không tìm thấy biến đó trong Execution Context hiện tại thì nó sẽ tìm ở Outer Environment.
Trong b(), text không có nên nó tìm biến text ở Outer Environment là ở Global, mà do hoisting nên text mới khởi tạo chứ chưa gán giá trị nên kết quả là undefined.
Ta chỉnh code lại một tý, thì kết quả là 'in a' do Outer Environment của b() đã khác:
Test yourself
Bạn vào link dưới đây
http://madebyknight.com/javascript-scope/
Trừ câu cuối là closure ra, nếu bạn làm đúng hết và giải thích rõ tại sao thì phần scope xem như đã khá vững.
Kết luận
Thực ra bạn hiểu thì dễ nhưng để giải thích cho người khác thì phải dùng từ ngữ làm sao để họ phân biệt được. Và mục đích 6 bài đầu là để giải thích những vấn đề về Scope trong Javascript. Đó là lý do mình chọn những từ 'jargon' như: Lexical Environment, Global Environment, Execution Context, Execution Stack,vv Vì đó là những từ 'đúng chuẩn', với lại cũng không thể Việt hóa chúng được