Difference between let and var

I saw the let variable today on a challenge for the first time, so i looked up the difference between let and var and found out that var is function scoped but let is block scoped. The definition of code block according to google is what ever between curly braces like in a function or statements grouped as condition.
But since var is function scoped that means is block scoped too since function is a code block.

So how to understand the difference between let and var and how to use them properly?
Thank you

Functions are blocks, true, but so are loops, if statements, etc

Check the list of challenges in Basic JavaScript, there may be something new for you to do

Not using var would normally be the way, then knowing the difference in how they work isn’t particularly important because you’d never be using one of them. As it is, var will work almost identically to let in many situations, but using let avoids the situations where it does make a difference and which are the reason for it being replaced. Ideally you are never going to write any code using var [outside of tutorials explaining the difference], because let (and const) are its replacement.


The difference is that a function can contain multiple blocks. An if statement with {}s is a block. A loop with {}s is a block. Just a set of {}s surrounding code is a block.

Keep it simple. Don’t use var. Only use const and let.

1 Like

any thing you want to add @snowmonkey ?

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 vars. 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 vars 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 vars, they don’t get “hoisted”.

let declared variables are not like vars, 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. :wink: