DEV Community

Cover image for Practical differences in variable declarations in JavaScript
Kostya Proshin
Kostya Proshin

Posted on

Practical differences in variable declarations in JavaScript

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.

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
Enter fullscreen mode Exit fullscreen mode

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.

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
Enter fullscreen mode Exit fullscreen mode

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.

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

Enter fullscreen mode Exit fullscreen mode

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.

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

Enter fullscreen mode Exit fullscreen mode

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.

(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
}

Enter fullscreen mode Exit fullscreen mode

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 🚀

Top comments (0)