JavaScript Closures: Giải Thích Từ A đến Z
Closure là một trong những khái niệm quan trọng nhất trong JavaScript. Bài viết này sẽ giải thích closure theo cách dễ hiểu nhất.
Minh Dev15 tháng 12 20248 phút4 thẻ
Share:
#javascript#closures#scope#fundamentals
Nội dung chính
Closure là gì?
Closure là một function có khả năng "nhớ" và truy cập vào các biến từ scope bên ngoài, ngay cả khi function đó đã được thực thi xong.
Nói đơn giản hơn: closure là sự kết hợp giữa một function và lexical environment của nó.
javascript
function outer() {
const message = "Hello from outer!"
function inner() {
console.log(message) // inner có thể truy cập 'message'
}
return inner
}
const greet = outer()
greet() // "Hello from outer!" — vẫn hoạt động dù outer() đã xongTại sao Closure lại quan trọng?
Closure cho phép chúng ta:
- Data encapsulation — ẩn dữ liệu khỏi global scope
- Factory functions — tạo ra các function với config khác nhau
- Memoization — cache kết quả tính toán
Ví dụ thực tế: Counter
javascript
function createCounter(initialValue = 0) {
let count = initialValue
return {
increment() { count++ },
decrement() { count-- },
getCount() { return count },
reset() { count = initialValue }
}
}
const counter = createCounter(10)
counter.increment()
counter.increment()
console.log(counter.getCount()) // 12
// 'count' không thể truy cập từ bên ngoài
// console.log(count) // ReferenceError!Closure trong vòng lặp — Cạm bẫy phổ biến
Đây là một trong những bug kinh điển nhất liên quan đến closure:
javascript
// Bug: tất cả đều in ra 5
for (var i = 0; i < 5; i++) {
setTimeout(() => console.log(i), 100)
}
// Fix 1: Dùng let thay vì var
for (let i = 0; i < 5; i++) {
setTimeout(() => console.log(i), 100) // 0, 1, 2, 3, 4
}
// Fix 2: Dùng IIFE
for (var i = 0; i < 5; i++) {
;((j) => {
setTimeout(() => console.log(j), 100) // 0, 1, 2, 3, 4
})(i)
}Memoization với Closure
javascript
function memoize(fn) {
const cache = new Map()
return function (...args) {
const key = JSON.stringify(args)
if (cache.has(key)) {
console.log('[cache hit]', key)
return cache.get(key)
}
const result = fn.apply(this, args)
cache.set(key, result)
return result
}
}
const expensiveCalc = memoize((n) => {
console.log('Calculating...')
return n * n
})
expensiveCalc(5) // Calculating... → 25
expensiveCalc(5) // [cache hit] → 25 (không tính lại)Kết luận
Closure là một trong những features mạnh nhất của JavaScript. Hiểu rõ closure sẽ giúp bạn:
- Viết code tốt hơn với proper encapsulation
- Tránh được các bug khó chịu liên quan đến scope
- Sử dụng functional programming patterns hiệu quả
Lần sau khi bạn thấy một function truy cập biến bên ngoài scope của nó — đó chính là closure đang hoạt động.
17Lượt xem