Closure trong Javascript - Phần 1: Lexical Environment
Bài đăng này đã không được cập nhật trong 4 năm
Xin chào các bạn, dạo này mình vẫn đang tìm tòi Javascript các thứ, có đọc qua đến phần closure. Để hiểu được closure thì trước tiên cần biết Lexical Environment là gì, vậy hãy cùng đi tìm hiểu.
1. Định nghĩa
Tất cà các hàm hay code block trong Javascipt và cả Global Object đều có một object được giấu tên, được gọi là Lexical Environment.
Một Lexical Environment có 2 phần:
Environment Record: một object chứa tất cả các biếnlocalthành thuộc tính của nó và một vài thông tin khác (như giá trị củathis)- Một reference (hãy coi nó như một mỗi liên kết) tới
Lexical Environmentbên ngoài.
2. Biến số (Variables)
Có thể nói, một biến số trong Javascript (variable) chính là một thuộc tính của Environment Record của môi trường đó. Khi bạn đang truy cập hay thay đổi một biến cũng có nghĩa là đang truy cập hay thay đổi thuộc tính đó của Environment Record.
Ví dụ:
let phrase = "Hello World";
phrase = "Goodbye World";
phrase = "Hello again";
Ở trong ví dụ này, biến phrase sẽ là một thuộc tính của object Environment Record được đính với Global Object.
- Lưu ý: Lexical Environment chỉ tồn tại dưới dạng specs, tức là chỉ tồn tại dưới mặt lý thuyết. Không có cách nào để
getobject này và thay đổi nó.
3. Khai báo hàm (Function Declarations)
Khi bạn khai báo một hàm trong Javascript, hàm đó cũng sẽ trở thành một method của Environment Record trong scope đó. Tuy nhiên, khi bạn khai báo (declare) một hàm, hàm đó có thể sử dụng được ngay lập tức, thậm chí trước khi bạn declare hàm đó.
say("Alice")
function say(name) {
console.log(`Hello ${name}`)
}
-> Hello Alice
4. Lexical Environment trong và ngoài (Inner and Outer Lexical Environment)
Khi một hàm được chạy thì ở đoạn đầu của quá trình đó, một Lexical Environment mới sẽ được tạo ra để chứa các biến và tham số.
Ví dụ:
let phrase = 'Hello';
function say(name) {
console.log(`${phrase} ${name}`)
}
say('Alice')
-
Lexical Environmentbên trong (của hàm say) có thuộc tính làname, là tham số được truyền vào. Khi gọi hàm này vớisay('Alice'), giá trị củanamelàAlice -
Lexical Environmentbên ngoài hàmsay(của Global Object) có chứa thuộc tínhphrasevà chứa luôn cả hàmsay. -
Lưu ý: khi chương trình muốn tìm một biến số, nó sẽ tìm từ Lexical Environment bên trong ra bên ngoài cho tới khi tìm đến Lexical Environment của Global Object. Ở ví dụ trên, chương trình đã không tìm thấy biến
phraseởLexical Environmentbên trong hàmsaynên nó đã tìm ở bên ngoài.
Đó là những điều cơ bản về Lexical Environment, chúng ta sẽ quay lại với Closure ở phần tiếp theo. Bạn có thể đọc thêm ở đây.
All rights reserved