Closure occurs when a function remembers variables from its outer scope and continues to access them even when executed in a different scope. Only functions have closures — not objects. To observe closure, a function must be called outside its original definition scope.
function greeting(msg) {
return function who(name) {
console.log(`${msg}, ${name}!`);
};
}
var hello = greeting("Hello");
var howdy = greeting("Howdy");
hello("Kyle"); // Hello, Kyle!
hello("Sarah"); // Hello, Sarah!
howdy("Grant"); // Howdy, Grant!The inner function who remembers msg from its outer scope, even after greeting finishes executing.
function counter(step = 1) {
var count = 0;
return function increaseCount() {
count = count + step;
return count;
};
}
var incBy1 = counter(1);
var incBy3 = counter(3);
incBy1(); // 1
incBy1(); // 2
incBy3(); // 3
incBy3(); // 6The inner function increaseCount closes over both count and step, preserving and updating their values over time.
function getSomeData(url) {
ajax(url, function onResponse(resp) {
console.log(`Response (from ${url}): ${resp}`);
});
}The callback onResponse remembers url even after getSomeData has returned.
for (let [idx, btn] of buttons.entries()) {
btn.addEventListener("click", function onClick() {
console.log(`Clicked on button (${idx})!`);
});
}Each onClick function remembers its respective idx variable thanks to block scoping with let.
The this keyword refers to the execution context of a function call. Unlike scope, which is static and tied to where a function is defined, this is dynamic and depends on how the function is called.
function classroom(teacher) {
return function study() {
console.log(`${teacher} says to study ${this.topic}`);
};
}
var assignment = classroom("Kyle");
assignment(); // Kyle says to study undefinedCalled without context, this.topic resolves to undefined.
var homework = {
topic: "JS",
assignment: assignment
};
homework.assignment(); // Kyle says to study JSHere, this refers to the homework object.
var otherHomework = {
topic: "Math"
};
assignment.call(otherHomework); // Kyle says to study Mathcall sets this to otherHomework, allowing dynamic reuse of the function.
Closure lets functions preserve and access outer variables, while `this` provides dynamic context based on how a function is called. Understanding both concepts is essential for writing professional, maintainable JavaScript code.