There is an important distinction to be made between let and var. Both of these statements allow the developer to declare a variable. Let was introduced in Javascript ES6.

Before we explore the merits of using let over var, it’s helpful to know the functionality and limitations of var.

Var Functionality

JavaScript was created in 1995 in only 10 days. JavaScript lacked some major features with such a shortdevelopment. This wouldn’t have been a problem had the language not become so widespread in use.

For some time var was the only way to declare a variable. The scope of var is confusing for developers coming from different languages. Declaring variables before ES6 doesn’t work in the way they’d expect it to.

The confusion in part comes from the difference in global versus local declaration. Var makes it difficult to determine what variables are global or local. It’s easy to accidentally create a global object and have variables collide.

Var in Action

Variables declared with var are scoped differently than let declarations. Scoping is just another way to say, “where can these variables be accessed.” In this case, var variables are function scoped. This means they’re available only in the function they’ve been created in.

Variables not declared in a function become globally scoped. They are then made available throughout the entire code. Hence, where problems can arise if variables are declared more than once.

A regular declaration would look like this and there would be no problems in the code.

After running this through the console you’ll get 50, 100, which is standard. The next order of business is to put a local variable into a function and see how that changes things.
Here we’ll create a function that has the var height inside.

Again, this is a standard local variable and we haven’t come across any problems yet. The next example will show when you start to run into problems.

This code won’t work because height is scoped to only that function. Outside of the confines, the variable is not available.

Previous Workaround Methods

Originally, there was a few convoluted workaround methods to determine global versus local scope differentiation. The one we’ll look at is called IIFE (Immediately Invoked Function Expression). It’s an awkward way to work with lack of a block scope.

Those not familiar with JavaScript will be confused by this pattern. Why are there so many parentheses? Why doesn’t the function have a name?

Another problem you’ll run into, is with hoisting. The JavaScript interpreter makes two passes through a section of code. The first pass processes the variables and function declarations. The second pass processes undeclared variables and function expressions.

Block scoping with the let keyword avoids this type of workaround design pattern.

Let Functionality

The let variable declaration, allows for variables to be limited in scope. This is different to the var keyword, which either defines the variable locally or globally, regardless of scope.

Let variables have their scope in the block they’re defined in. ES6 introduced this direct mechanism to block scoping. The let keyword is like a sibling to var. Here is an example of the two of them together.

The let declaration both expresses and enforces block scoping. Essentially, let is best used when you have to create limited scope declarations.

Anything before ES6 doesn’t have the let functionality. There are a few transpilers that convert from ES6 to ES5 if a project calls for it.

Overall, you shouldn’t need to replace legacy code (var declarations) with let keywords. It’d be wise to use let over var, now that the functionality has been added to ES6. You’ll avoid scoping problems, and variables that can override one another.


  • Andrey

    Let functionality example is incorrect. You willn`t get 1 in console.log(x); , cose x is local variable of func example.
    You should call console.log within the function, for the sake of effect you talking about.

  • Elana

    In your example above, x is not defined outside of the function either. Line 11 should also be undefined.