Sure, but it’ll be a kinda long one.
So for the first twenty years of javascript, we had one option: var
. Every variable was a var
, whether explicitly declared as one. Each of these create a var
:
// isEven is a global var
// num is a locally-scoped var to isEven
function isEven(num){
// remainder is also locally-scoped
var remainder = num%2;
// what happens here?
message = Boolean(remainder) ? "Odd" : "Even";
return message;
}
So functions defined like this are converted internally to var isEven=function isEven()
. Parameters are created as locally-scoped var
s. And var
declarations are contained by the function scope where they are declared. But what happened in that last one, with message
? We set a value to it, but never declared it!
In that last case, message
is declared for us, in the global scope. Early creators of javascript allowed for very loose coding habits, including not explicitly declaring our variables. It’s bad practice, but it was being done - and by the time they could change it, there was enough code that depended on it that it would break too much.
So an explicitly declared var
is contained by the function that declared it. Without that var
, they’re declared (assigned to the lookup table) in the global scope. But in either case, var
does something that can be a gotcha.
When a function is first being read by the javascript engine, it lexes your function. This means it breaks it down and scans for keywords, sets up a variable lookup table for that function, and allocates the var
declarations to that lookup table. It doesn’t assign the values before the function, but it sets the name itself aside. What that means is, before our function runs, all the var
s exist, with an undefined
value.
let
and const
are different, in two ways:
- first, the scope is much more restricted: they are limited to the nearest
{ }
curly braces. Might be an if or for, might be a function, might simply be a block of code explicitly contained by { }
, which is legal javascript.
- second, they are not allocated in that lookup table in advance. They are only created when they are encountered in the normal flow of the function. They can be declared at any point, but unlike
var
s, they don’t get “hoisted”.
let
declared variables are not like var
s, in that they won’t automatically go to the global scope. They enforce explicit declaration, and they are intentionally placed. They are not encouraging of sloppy coding like we used to do.
If your code is running in strict mode, the way var
works changes. Not explicitly declaring them will cause an error, so they are more enforced.
But they are still either functionally or globally scoped, and hoisted where let
and const
are block scoped and not hoisted.
EDIT: I’m well aware i over-answered, and intentionally left some questions open. When you encounter them, try out different things to see what happens and keep on asking.