Javascript Variable Declaration
JavaScript has three ways to declare variables, each with different scoping rules and use cases.
When to Use Each
const: Default choice for most variables
let: When you need to reassign values (counters, flags, accumulators)
var: Rarely needed in modern code; mainly for legacy support or specific patterns
The introduction of let and const in ES6 significantly improved JavaScript's variable scoping and made code more predictable and maintainable.
1. var (Function-Scoped)
var is the original way to declare variables in JavaScript. It has function scope and is hoisted to the top of its scope.
Characteristics:
1. Function-scoped (not block-scoped)
2. Hoisted to the top of its scope
3. Can be redeclared and updated
4. Creates a property on the global object (when declared globally)
// Function-scoped example
function doSomething() {
if (true) {
var x = 10; // Available throughout the function
}
console.log(x); // 10 - accessible outside the block
}
// Hoisting example
console.log(y); // undefined (hoisted but not initialized)
var y = 5;
// Redeclaration
var z = 1;
var z = 2; // No error
console.log(z); // 2
2. let (Block-Scoped)
let was introduced in ES6 and provides block-level scoping, which is generally more predictable.
Characteristics:
1. Block-scoped ({ } boundaries)
2. Not hoisted in the same way as var (temporal dead zone)
3. Can be updated but not redeclared in the same scope
4. Doesn't create properties on the global object
Example Use Cases:
// Block-scoped example
function exampleLet() {
if (true) {
let x = 10; // Only available in this block
console.log(x); // 10
}
// console.log(x); // ReferenceError: x is not defined
}
// Loop variables (ideal use case)
for (let i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i); // Logs 0, 1, 2, 3, 4 (not 5,5,5,5,5 like with var)
}, 100);
console.log(i);
}
// Can be updated but not redeclared
let count = 0;
count = 1; // Allowed
// let count = 2; // SyntaxError: Identifier 'count' has already been declared
3. const (Block-Scoped Constants)
const is also ES6 feature for declaring constants - variables that cannot be reassigned.
Characteristics:
1. Block-scoped like let
2. Must be initialized during declaration
3. Cannot be reassigned after declaration
4. For objects/arrays, the reference is constant but properties/elements can be modified
Example Use Cases:
// Constants that shouldn't change
const PI = 3.14159;
const API_URL = "https://api.example.com";
// Object with const - properties can be modified
const person = {
name: "John",
age: 30
};
person.age = 31; // Allowed - modifying property
// person = {name: "Jane"}; // Error - cannot reassign
// Array with const - elements can be modified
const colors = ["red", "green"];
colors.push("blue"); // Allowed
// colors = ["purple"]; // Error - cannot reassign
// Configuration objects
const CONFIG = {
timeout: 5000,
retries: 3,
baseURL: "https://api.example.com"
};
What Happens When You Don't Declare Variable Types in JavaScript
When you don't use var, let, or const to declare a variable, JavaScript automatically creates a global variable (in non-strict mode). This is generally considered bad practice and can lead to bugs.
Problem Scenario:
// In file1.js
function initApp() {
config = { theme: "dark" }; // Accidentally global
}
// In file2.js (loaded later)
function updateConfig() {
config = { theme: "light" }; // Modifies the same global variable!
}
Solution:
// Always declare variables properly
function initApp() {
const config = { theme: "dark" }; // Properly scoped
return config;
}
function updateConfig(currentConfig) {
return { ...currentConfig, theme: "light" }; // No side effects
}
Best Practices
1. Always declare variables with const, let, or var
2. Use 'use strict' to catch undeclared variables
3. Lint your code - tools like ESLint will flag this error
4. Prefer const/let over var for better scoping
// Good
const calculateTotal = (items) => {
let total = 0;
for (let item of items) {
total += item.price;
}
return total;
};
// Bad (creates global variable)
const calculateTotalBad = (items) => {
total = 0; // Missing declaration!
for (item of items) { // Also missing declaration!
total += item.price;
}
return total;
};