Practical differences in variable declarations in JavaScript
Tags: javascript, programming, variables
Published: 2021-06-19 15:35:41

Variables in JavaScript behave differently depending on whether the `const`, `let`, or `var` statement was used at the moment of declaration.

When I was looking for a web developer job — this topic was among the first questions on almost every technical interview I attended.

It’s not surprising — it is one of the fundamental things in JavaScript every professional web developer must know.

I hope this post would help if you are preparing for a tech interview, or it would be a good refresher if you already got a job.

#Scope isolation

Accessibility of variables declared using `const` or `let` will differ from variables created with the `var` statement. The former are block-scoped bindings, latter — function-scoped.

In practice, it means that if we create a variable using `const` or `let` inside a block delimited by a pair of braces — it will be accessible there and in all nested blocks, but it won’t be visible for code outside that block.

It’s not the case with `var` variables — they won’t be isolated in the block where they were defined. So they will be visible for code outside.

```javascript
if (true) {
  const bar = '👾'  // `let` will behave identically
  if (true) {
    console.log(bar) // prints value
  }
}
console.log(bar) // throws ReferenceError: bar is not defined

if (true) {
  var foo = '👽'
  if (true) {
    console.log(foo) // prints value
  }
}
console.log(foo) // also prints value
```

If we declare a variable inside a function — doesn’t matter with the `var`, `const`, or `let` statement — it will be isolated in this function’s scope.

```javascript
function lilu () {
  var foo = "👽" // `let` and `const` will behave similarly
  if (true) {
    console.log(foo)
  }
}
lilu() // prints value
console.log(foo) // throws ReferenceError: foo is not defined
```

#Reassignment

When declaring a variable using the `const` statement, we create a permanent reference to a value — this reference can’t be changed. Because of that, a `const` variable must be initialized to a value when declared.

In contrast, `let` and `var` variables can be reassigned. Thus, it is not mandatory to assign values to them at the moment of declaration.

```javascript
const lilu // throws SyntaxError: Missing initializer in const declaration
const lilu = "👾"
lilu = "👽" // throws TypeError: Assignment to constant variable

var foo
let bar
console.log(foo) // prints undefined
console.log(bar) // prints undefined

foo = "👾"
bar ="👽"
console.log(foo) // prints value
console.log(bar) // prints value

```
Though a `const` variable holds a permanent reference to a value — it doesn’t relate to the immutability of data itself. For instance, if a `const` variable points to structural type data, like an object or array— you can alter this value.

#Redeclaration

It is possible to declare a `var` variable with a duplicate name without triggering errors. In the case of `const` and `let` variables — redeclaration is forbidden — their identifiers must be unique.

```javascript
var foo = "Hello"
var foo = "World!"
console.log(foo) // prints "World!"

const bar = "Hello"
const bar = "World!" // throws SyntaxError: Identifier 'bar' has already been declared

var lilu = "Hello"
const lilu = "World!" // throws SyntaxError: Identifier 'lilu' has already been declared

```

#Initialization

Variables declared with the `var` statement are automatically initialized at the top of the current scope — at that point, they hold `undefined` value. Due to that, it is possible to use them before the line where we declared them.

It is not the case with `const` and `let` variables — they are not initialized until the interpreter encounters lines with their declarations. So we can’t use `const` and `let` variables before the declaration.

```javascript 
(function () {
  /* current scope */
  console.log(foo) // prints undefined
  foo = 1
  console.log(foo) // prints 1
  var foo = 2
  console.log(foo) // prints 2
})()

{
  /* current scope */
  console.log(lilu) // throws ReferenceError: Cannot access 'lilu' before initialization
  const lilu = 1 // `let` will behave identically
}

```

It's common to declare variables using `const` in situations when you don't need to reassign them, and `let` — when you plan to change their values. Usage of `var` variables can be less intuitive and can lead to tricky bugs.

There you have it!  Thank you for reading!

... and I wish you good luck with your next tech interview 🚀