Closure = function + lexical environment nơi nó được khai báo. Inner function truy cập biến outer function sau khi outer đã return.
function outerFunc() {
var name = "TutorialsPoint";
return function innerFunc() { console.log(name); };
}
let f = outerFunc(); f(); // "TutorialsPoint" — name vẫn sống nhờ closure
Ứng dụng thực tế
1. Mô phỏng Private Methods (Encapsulation)
JS không có private natively. Closure tạo scope riêng:
const counter = (() => {
let privateCounter = 0;
const changeBy = val => privateCounter += val;
return {
increment: () => changeBy(1),
decrement: () => changeBy(-1),
value: () => privateCounter
};
})();
console.log(counter.value()); // 0
counter.increment(); counter.increment();
console.log(counter.value()); // 2
counter.decrement();
console.log(counter.value()); // 1
2. Event Handlers trong vòng lặp
Vấn đề: var i shared → tất cả handler thấy cùng giá trị cuối.
// Sai
for (var i=0; i<4; i++) btn.addEventListener('click', () => alert(i)); // all alert 4
// Đúng: closure capture i per iteration (dùng let hoặc IIFE)
for (let i=0; i<4; i++) btn.addEventListener('click', () => alert(i)); // 0,1,2,3
Lưu ý: let trong loop tạo binding mới mỗi iteration → closure tự động đúng.