A click counter needs to remember its count without letting unrelated code change it. Scope determines where a variable is visible: calling a JavaScript function creates a scope whose local variables are not visible outside that function. section 11.1.1
Scope also makes closures useful. A function can keep access to variables that were in scope when it was created, even after the surrounding function finishes. That is why a click handler can continue updating a local count. Execution contexts and lexical environments help explain this behavior under the hood. section 5.6 section 11.1.1
Listing 11.1. The module pattern
const MouseCounterModule = function() { #A
let numClicks = 0; #B
const handleClick = () => { #C
alert(++numClicks); #C
}; #C
return { #D
countClicks: () => { #D
document.addEventListener("click", handleClick); #D
} #D
}; #D
}();
assert(typeof MouseCounterModule.countClicks === "function", #E
"We can access module functionality"); #E
assert(typeof MouseCounterModule.numClicks === "undefined" #F
&& typeof MouseCounterModule.handleClick === "undefined" , #F
"We cannot access internal module details"); #F
The module-pattern listing puts the count inside a function scope and returns an object with a public method. The method can use the hidden state through a closure; outside code cannot read the count directly. section 11.1.1
Keep separate function scopes in mind when extending a module: methods added in another function do not gain access to the first function’s local variables. Historically, JavaScript relied on global and function-level variables; block-level variables are a more recent addition. section 11.1.1 section 1.1




















