For the sake of conversation, lets say that every closure creates a "scope" where variables are defined - everything within the closure/scope can access variables, anything outside cannot. With that said, there are two different types of implied closures you should be aware of.
This is not an exhastive description of how closures work, but more of description of the basic practical concepts as they relate to this question. There is much more going on with how call stacks are created, lexical scoping, "global" scope within NodeJS, iframes, sandboxing, var
vs const
/let
, block vs function scopes, and other concepts which I will leave to the reader to discover on their own.
The browser/window/global scope
In the browser, you have the top-level scope (basically window
, often referred to as the "global" scope). This kind of acts as a closure in that all "non-enclosed" variables are defined as part of the window scope and are available to most other code running on that page. For example, if you include the following script in the browser, x
is part of the global/window scope, whereas y
and z
are enclosed inside their own nested scopes.
// basic-script.js
// x becomes part of the global/window scope
const x = 10;
(() => {
// y is enclosed in a separate, nested closure
const y = 20;
// x is available in this nested scope/closure
console.log('The sum of x and y is', x + y);
function foo() {
// z is enclosed in a separate, nested closure
const z = 5;
// x and y are both available in this nested scope/closure
console.log('The sum of x y and z is', x + y + z);
}
foo();
// z is not available to the parent scope
console.log(z); //-> undefined
})();
// y is not available to the parent scope
console.log(y); //-> undefined
<script src="basic-script.js"></script>
<script>
// this works because x is not enclosed
console.log('The value of x is', x);
// y and z are not available as they are inside a separate closure
console.log(y, z); //-> undefined, undefined
</script>
JavaScript modules
When you write JavaScript which is imported or required by other modules, every module is automatically wrapped in its own closure. For example, if you were to import/require the above basic-script.js
into another JavaScript file, the above would be automatically enclosed like this:
(function() {
var x = 10;
// ... other code removed for brevity
})();
There is some other magic going on for exposing exports and so forth, but that's beyond the scope of this answer (pun intended). If JS modules were not wrapped in their own closure, then you would have a mess of naming collisions and reference issues, as well as a security nightmare.
So to answer your question, yes - your second example shares a closure with "x" - the closure is implicitly created depending on your environment.