Explain Codes LogoExplain Codes Logo

What is the difference between "let" and "var"?

javascript
hoisting
temporal-dead-zone
javascript-features
Anton ShumikhinbyAnton Shumikhin·Aug 30, 2024
TLDR

let brings block-level scope to JavaScript, allowing the variable to be confined within curly braces {}. This directly avoids hoisting issues and wards off unintended access outside the block. On the other hand, var spans a function or global scope. It can be redeclared within the same scope, which may lead to spinning heads and potential code conflicts.

Block Scope with let:

{ let blockScoped = 'Behind these braces, I am secure.'; } console.log(blockScoped); // ReferenceError: blockScoped is not defined. Oops!

Function/Global Scope with var:

{ var functionScoped = 'Oh, I can wander anywhere!'; } console.log(functionScoped); // Fires: 'Oh, I can wander anywhere!'

Embrace let to write maintainable and less error-prone code, as it lets you set the rules on variable scope, in turn providing more predictability, much needed when crafting complex applications.

The nitty-gritty of hoisting and the TDZ

Hitting the ceiling with hoisting

Though both let and var share characteristics like hoisting that moves variables to the top of scopes, only the variables declared with var are initialized to undefined during hoisting. With let, we sleepwalk into what's known as the Temporal Dead Zone(TDZ) - a no-access period that extends until the variable is assigned.

Error the side of caution with early access

This understanding of the TDZ can be a lifesaver, saving you from uncaught ReferenceError nightmares:

// Fasten your seatbelts with `let` console.log(myLetVar); // ReferenceError: myLetVar is not defined. Oops, I did it again! let myLetVar = 'Now we are safe'; // Bumping into `undefined` with `var` console.log(myVar); // Returns undefined, no harm done var myVar = 'I am everywhere';

The curious case of loops

This difference between let and var reflects distinctly in loops, as each loop iteration with let gets a new variable, thereby solving the infamous closure problem:

// The magic of `let` in for-loops for (let i = 0; i < 5; i++) { setTimeout(() => console.log(i), 100); // Logs the numbers 0 to 4, who's laughing now? } // The tragedy of `var` in for-loops for (var j = 0; j < 5; j++) { setTimeout(() => console.log(j), 100); // Logs the number 5, five times. Did you expect this? }

Advanced patterns and commonly faced errors

The perils of redefining and overshadowing

While let proves to be a strict headmaster preventing redeclaration within the same scope, var stands at the other end of the spectrum potentially leading to conflicts and headaches:

let gadget = 'smartphone'; let gadget = 'laptop'; // The SyntaxError bell rings: Identifier 'gadget' has already been declared var tool = 'hammer'; var tool = 'screwdriver'; // No error, but now tool is a screwdriver, not a hammer. Wait, what?

Protecting the global universe

When making global declarations, var adds a global object property. This can be overshadowed by later declarations, while let doesn't partake in this cluttering game:

var globalVar = 'You can find me as window.globalVar'; let globalLet = 'I prefer a low profile, window.globalLet is not my style';

Embracing immutability with const

const is another keyword akin to let and var which, in addition to preventing redeclarations, also impedes reassignments, thereby enhancing immutability:

const pi = 3.14159; pi = 3.14; // TypeError: No reassignments please, pi minds its own const-ant value.

Compatibility and technical advice

The eccentric browser behavior

Unfortunately, not all browsers interpret let the same way hence checking compatibility is vital for cross-browser code. But don't fret, community tools like Babel can transpose let down to var for broader support.

Modern coding guidelines

Embrace let when you can and var when you must. That's the mantra. As ES6 and beyond continues to shape modern JavaScript development, developers continue to relish in the safety, immutability and predictability that let offers.