2

It was my understanding that variables created with let in Javascript cannot be global. I thought that meant that the variable only lived in that particular file.

However, when I make a simple/contrived example:

A.js:

let a = 5;

B.js:

console.log(a);

index.html:

<script type="text/javascript" src="A.js"></script>
<script type="text/javascript" src="B.js"></script>

it logs 5! Strangely though if I log window.a, that logs as undefined, so a global variable is not being created.

My question is, how is the variable getting shared between files without being a global variable?

machineghost
  • 33,529
  • 30
  • 159
  • 234
  • it's in scope of the global scope :) – Icepickle Mar 26 '19 at 21:36
  • @Bergi, that's not the same question. This talks about whether the particular scope that top level `let` occupies is shared between scripts or not. Your question addresses whether or not it exists on the `global` / `window` object. – Patrick Roberts Mar 26 '19 at 22:02
  • [Related](https://stackoverflow.com/q/28776079/1541563), but not a duplicate. – Patrick Roberts Mar 26 '19 at 22:07
  • @PatrickRoberts The duplicate explains how `let a` declares a global variable without `a` become a property of `window`. Seems like it answers machineghost's question perfectly fine. – Bergi Mar 26 '19 at 22:07
  • The related question answers _Do these declarations create properties on the global object?_ It does not even address the fact that the variable is shared between synchronously loaded scripts. – Patrick Roberts Mar 26 '19 at 22:12

2 Answers2

3

It stays inside the current scope, the most outer block scope (or global scope as Bergi so nicely mentions), so this would work

<script>
let world = 'world';
</script>
<script>
console.log( `hello ${world}` );
</script>

Where as this would not

<script>
{
  let world = 'world';
}
</script>
<script>
console.log( `hello ${world}` );
</script>

it really doesn't matter that you are using 2 different files. In the end, all the scripts that get loaded get put behind each other, optimized and executed

Icepickle
  • 12,689
  • 3
  • 34
  • 48
  • Stupid question, how is `{ let world = 'world'; }` valid Javascript? That looks like a let statement inside an object literal (ie. invalid JS) to me? – machineghost Mar 26 '19 at 21:41
  • 1
    @machineghost it's a block scope ;) – Icepickle Mar 26 '19 at 21:41
  • Wackiness. I've been using Javascript for a decade and never knew block scopes were a thing. – machineghost Mar 26 '19 at 21:43
  • 1
    "*most outer block scope*" - it's called the global scope for simplicity :-) – Bergi Mar 26 '19 at 22:02
  • @Bergi you always know how to say it in a correct simple way :D – Icepickle Mar 26 '19 at 22:07
  • I think the most confusing thing about all of this to me is that I've heard so many times "use `let` or `const` instead of `var` because they avoid creating global variables, which as we all know are bad". This new understanding completely destroys that, and now (in terms of preventing file A from accidentally messing with something from file B) `let`/`const` seems to offer no benefit over `var`. But it's all making more sense now, thanks! – machineghost Mar 26 '19 at 22:41
1

It's a regular variable in the global scope.

Using multiple script sources doesn't mean using multiple interpreters.

Webber
  • 4,672
  • 4
  • 29
  • 38
  • 1
    "regular variable in the global scope" doesn't make sense; how is that different from a global variable? – machineghost Mar 26 '19 at 21:43
  • 1
    It's not different. You just can't access it as a property of window, as it is never assigned to window. For that you would have to do window.a = 5 instead. – Webber Mar 26 '19 at 21:47
  • I guess this just doesn't match any explanation I've been given of global variables before. The fact that they were a property of window and the fact that they could be accessed anywhere used to be inherently linked together, so separating the two goes against my previous education. Thanks! – machineghost Mar 26 '19 at 22:31