How to Use JavaScript variables?

Legacy variables

var used to be the only way we could define variables until let was put into the ECMAScript standard and const a few years later.

If var already handled variables, where is the need for let and why has var become JavaScript's black sheep? There are a couple of reasons for that:

  1. var variables are global or function scoped.
    • Makes it very easy to overwrite values in parent scopes since var does not treat blocks as scopes.
  2. var variables can be used without declaring them first, as var declarations are hoisted to the top of the current scope.
  3. Loops using var share the same counter variable.

Avoid var

Avoid using var unless absolutely necessary. Use const for constants and let for variables. This will save us from a lot of self-inflicted headache.

Mutation

We can modify the value of a var variable by assigning it a new value using the = symbol.

var counter = 100 // initialized to 100
counter = 99 // mutated to 99

Initialization

We can declare a var variable without immediately initializing it with a value.

var counter
counter = 99
console.log(counter) // 99

In the above example we declare a variable counter and use it only after we have given it a value.

counter = 99
console.log(counter)
var counter

This example would have given us an error if we had used let, but JavaScript hoists var declarations to the top of the scope making the above code equivalent to the below code.

var counter // hoisted to top
counter = 99
console.log(counter)

Scope

var variables are not block scoped and only respects the global and function scope.

Code example: everything looks good

What do we expect to be printed by the last console.log here?

var x = 0 // global scope
console.log(x) // 0
function abc() {
var x = 2 // function abc scope
console.log(x) // 2
}
abc()
console.log(x) // 0

This behaves exactly as we would have expected it to. The first x is in its own truly global scope and the x inside the function abc has its own scope.

Code example: blocks are not scopes

Here we have a block inside the function that also declares and initializes a variable x. What do we expect to be printed by the various console.log statements in this case?

var x = 0 // global scope
console.log(x) // 0
function abc() {
var x = 2 // function abc scope
console.log(x) // 2
{ // new block
var x = 4
console.log(x) // 4
}
console.log(x) // 4 (why?)
}
abc()
console.log(x) // 0

The reason the last console.log in the function abc prints 4 instead of 2 is that var variables are not block scoped. When we declare a variable x inside the block and give it a value, we end up mutating the original x inside the function.