# Difference between var, const and let


There are 3 ways to declare a variable in Javascript: using one of the keywords `var`, `const` or `let`.

Prior to ES6, `var` used to be the only way to declare a variable. You had no other choice. However, it had some weird and unexpected behavior, which often resulted in hard to debug errors.

Intuitively, you would think variable declared with `var` is block scoped. Variable declared in, for example, `if` statement, or a `for` loop, is visible only in the scope of that statement or loop.

Nope.

_It is **function** scoped._

What this means is that a variable declared in a function would be visible in the entire function, even outside of `if` blocks or loops. If declared outside of functions, it becomes global.

```js
var test1 = 1; // Global, as expected

function testFunction() {
var test2 = 2; // Function scoped, as expected

if (true) {
var test3 = 3; // Still function scoped
console.log(test3); // Logs 3, still ok
}

console.log(test3); // Still logs 3 ???
}
```

## Let and var

Main difference between `var` and `let` is that `let` is block scoped. Block scoping means that a variable is visible only in the block scope it is declared, block being any block of code surrounded by curly braces `{}` such as a `for` loop or `if` statement, including any nested sub-blocks.

```js
let test1 = 1; // Global, as expected

function testFunction() {
let test2 = 2; // Function scoped, as expected

if (true) {
let test3 = 3; // Still function scoped
console.log(test3); // Logs 3, still ok
}

console.log(test3); // Uncaught ReferenceError: test3 is not defined
}
```

Same example as previous one, this time all variables are declared with `let` instead of `var`. Now, if we use a variable declared with `let` in an `if` statement outside of it, we get a reference error.

Inside of a block scope, `let` is defined in it and all nested blocks, but not outside of it, while `var` is defined in the entire function, regardless of blocks.

Another main difference between `var` and `let` is that `var` is initialized with `undefined` by default. `Let`, on the other hand, is not initialized at all until interpreter evaluates it. Accessing `var` before its declaration will return `undefined`, but `let` would result in reference error.

## Const

`Const` is very similar to `let`, with some additional properties.

Initializing `const` is required, unlike `let`. Declaring another `const` with the same name is not possible.

```js
let foo; // ok
foo = "foo"; // ok

const bar; // SyntaxError: Missing initializer in const declaration
const bar = "bar"; // ok
```

`Const` creates a read-only reference to the value. This does not mean a value cannot be changed, it means that you cannot re-assign to the same identifier again.

Also, it does not mean the value becomes immutable. It still can be changed, but not by re-assigning. For example, you could change properties of an object, or remove from an array, but not by assigning new object or an array.

## Conclusion

`Var` is slowly becoming a thing of the past. Most browsers support `let` and `const` today, and are much easier to work with than `var`. Some widely used libraries and old apps still use `var`, so it is still widespread, but for new projects it is rarely used. It is much safer to use `const` by default, only changing it to `let` when re-assigning is necessary.

