Calling a function creates a scope for its local variables: they are visible inside that function, but hidden from outside code. JavaScript’s lexical environment is the internal mechanism behind scoping; “scope” is the common shorthand. section 5.4 section 11.1.1
Historically, before ES6, JavaScript associated lexical environments only with functions, so variables could only be function-scoped. ES6 added scopes for blocks and catch clauses, addressing a source of confusion for developers familiar with other C-like languages. section 5.4
Function scope can also hide implementation details. A module function can keep variables such as a click counter private while returning an interface whose methods use closures to retain access to them. 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 shows a function-local click counter retained by a returned public interface. section 11.1.1
