JavaScript const Keyword Complete Guide
Understanding JavaScript const Keyword
The const keyword was introduced in ES6 as a way to declare block-scoped variables that cannot be reassigned. Unlike var, const provides true block scoping and immutability for variable bindings, making code more predictable and less prone to errors.
Key Characteristics of const Keyword
Block Scoped- Variables are accessible only within the block where they're declaredImmutable Binding- Cannot be reassigned after declarationMust Be Initialized- Requires immediate assignment during declarationTemporal Dead Zone- Cannot be accessed before declaration
Basic const Declaration Examples
Learn the fundamental ways to declare and use variables with const keyword. These examples demonstrate proper declaration patterns and the immutability characteristics of const.
1// Example 1: Basic const declaration with primitive values
2const age = 25;
3const name = "John Doe";
4const isActive = true;
5const PI = 3.14159;
6
7console.log(age); // 25
8console.log(name); // "John Doe"
9console.log(isActive); // true
10console.log(PI); // 3.14159
11
12// Example 2: Attempting reassignment throws error
13const MAX_USERS = 100;
14console.log(MAX_USERS); // 100
15
16// MAX_USERS = 200; // ❌ TypeError: Assignment to constant variable
17// MAX_USERS++; // ❌ Error: Would require reassignment
18
19// Example 3: const requires initialization
20const API_KEY = "abc123def456"; // ✅ Correct - initialized
21// const UNINITIALIZED; // ❌ SyntaxError: Missing initializer
22
23// Example 4: Multiple const declarations
24const WIDTH = 1920, HEIGHT = 1080, DEPTH = 255;
25console.log(`Resolution: ${WIDTH}x${HEIGHT}`); // "Resolution: 1920x1080"
26
27// Example 5: const with computed values
28const TAX_RATE = 0.07;
29const price = 100;
30const total = price * (1 + TAX_RATE);
31console.log(total); // 107Declaration Rules
Initialization Required- Must assign value during declarationNo Reassignment- Cannot change value after initializationBlock Scope- Only accessible within declaring blockUPPERCASE Convention- Use for constants that never change
const with Objects and Arrays
While const prevents variable reassignment, it doesn't make objects or arrays immutable. You can modify the contents of const objects and arrays, but you cannot reassign the variable to a different object or array.
1// Example 6: const with objects - properties can be modified
2const user = {
3 name: "Alice",
4 age: 30,
5 email: "alice@example.com"
6};
7
8// These modifications are ALLOWED ✅
9user.age = 31; // Modify property
10user.city = "New York"; // Add new property
11user.email = "newemail@example.com"; // Change property
12
13delete user.email; // Delete property
14
15console.log(user); // { name: "Alice", age: 31, city: "New York" }
16
17// This reassignment is NOT allowed ❌
18// user = { name: "Bob" }; // TypeError: Assignment to constant variable
19
20// Example 7: const with arrays - elements can be modified
21const colors = ["red", "green", "blue"];
22
23// These modifications are ALLOWED ✅
24colors[0] = "orange"; // Change element
25colors.push("yellow"); // Add element
26colors.pop(); // Remove element
27colors.splice(1, 1, "purple"); // Replace element
28
29console.log(colors); // ["orange", "purple", "blue"]
30
31// This reassignment is NOT allowed ❌
32// colors = ["pink", "cyan"]; // TypeError: Assignment to constant variable
33
34// Example 8: Nested object modification
35const config = {
36 api: {
37 baseUrl: "https://api.example.com",
38 timeout: 5000
39 },
40 features: ["auth", "upload", "download"]
41};
42
43config.api.timeout = 10000; // ✅ Allowed - modifying nested property
44config.features.push("search"); // ✅ Allowed - modifying array
45
46console.log(config.features); // ["auth", "upload", "download", "search"]Object/Array Behavior with const
Binding Immutability- Variable cannot be reassigned to new object/arrayContent Mutability- Object properties and array elements can be modifiedReference Preservation- Variable always points to the same object/arrayNested Modification- Can modify deeply nested properties and elements
Block Scoping with const
const variables are block-scoped, meaning they are only accessible within the block where they are declared. This provides better control and prevents variable leakage compared to var.
1// Example 9: Block scope demonstration
2function demonstrateBlockScope() {
3 const globalInFunction = "I'm accessible in entire function";
4
5 if (true) {
6 const blockScoped = "I'm only accessible in this block";
7 console.log(blockScoped); // ✅ "I'm only accessible in this block"
8 console.log(globalInFunction); // ✅ "I'm accessible in entire function"
9 }
10
11 console.log(globalInFunction); // ✅ "I'm accessible in entire function"
12 // console.log(blockScoped); // ❌ ReferenceError: blockScoped is not defined
13}
14
15demonstrateBlockScope();
16
17// Example 10: const in different blocks
18const globalConst = "I'm global";
19
20function testScopes() {
21 const globalConst = "I'm shadowing the global"; // Different variable
22 console.log(globalConst); // "I'm shadowing the global"
23
24 if (true) {
25 const globalConst = "I'm in block scope"; // Another different variable
26 console.log(globalConst); // "I'm in block scope"
27 }
28
29 console.log(globalConst); // "I'm shadowing the global"
30}
31
32testScopes();
33console.log(globalConst); // "I'm global"
34
35// Example 11: const in switch statements
36const color = "red";
37
38switch (color) {
39 case "red":
40 const redMessage = "This is red";
41 console.log(redMessage); // ✅ "This is red"
42 break;
43 case "blue":
44 // console.log(redMessage); // ❌ ReferenceError: redMessage not defined
45 const blueMessage = "This is blue";
46 break;
47}const in Loops and Iteration
const behaves differently in various loop types. In for...of and for...in loops, const creates a new binding for each iteration, while traditional for loops require let for the counter variable.
1// Example 12: const in for...of loops
2const fruits = ["apple", "banana", "orange"];
3
4for (const fruit of fruits) {
5 console.log(fruit); // "apple", "banana", "orange"
6 // fruit = "grape"; // ❌ Error: Assignment to constant variable
7}
8
9// Example 13: const in for...in loops
10const person = { name: "John", age: 30, city: "Boston" };
11
12for (const key in person) {
13 console.log(`${key}: ${person[key]}`);
14 // key = "newKey"; // ❌ Error: Assignment to constant variable
15}
16
17// Example 14: Traditional for loop requires let
18// This does NOT work with const:
19// for (const i = 0; i < 5; i++) { } // ❌ Error: Assignment to constant variable
20
21// Correct approach with let:
22for (let i = 0; i < 3; i++) {
23 const iterationMessage = `Iteration ${i}`;
24 console.log(iterationMessage); // "Iteration 0", "Iteration 1", "Iteration 2"
25}
26
27// Example 15: const with array methods
28const numbers = [1, 2, 3, 4, 5];
29
30numbers.forEach((number) => {
31 const squared = number * number;
32 console.log(squared); // 1, 4, 9, 16, 25
33});
34
35const doubled = numbers.map((number) => {
36 const double = number * 2;
37 return double;
38});
39console.log(doubled); // [2, 4, 6, 8, 10]const with Functions and Modules
const is commonly used for function expressions, arrow functions, and module exports. It provides clear intent that the function reference should not be reassigned.
1// Example 16: const with function expressions
2const calculateArea = function(radius) {
3 const PI = 3.14159;
4 return PI * radius * radius;
5};
6
7console.log(calculateArea(5)); // 78.53975
8
9// calculateArea = function() { return 0; }; // ❌ Error: Assignment to constant variable
10
11// Example 17: const with arrow functions
12const multiply = (a, b) => a * b;
13const greet = (name) => `Hello, ${name}!`;
14
15console.log(multiply(4, 5)); // 20
16console.log(greet("Alice")); // "Hello, Alice!"
17
18// Example 18: const in module pattern
19const MathUtils = {
20 PI: 3.14159,
21
22 circleArea: function(radius) {
23 return this.PI * radius * radius;
24 },
25
26 circleCircumference: function(radius) {
27 return 2 * this.PI * radius;
28 }
29};
30
31console.log(MathUtils.circleArea(10)); // 314.159
32
33// MathUtils = {}; // ❌ Error: Assignment to constant variable
34
35// Example 19: const with imported modules
36// In module.js:
37// export const API_BASE_URL = "https://api.example.com";
38// export const MAX_RETRIES = 3;
39
40// In main.js:
41// import { API_BASE_URL, MAX_RETRIES } from './module.js';
42// console.log(API_BASE_URL); // "https://api.example.com"
43
44// Example 20: const for configuration objects
45const APP_CONFIG = {
46 version: "1.0.0",
47 environment: "production",
48 features: {
49 auth: true,
50 payments: false,
51 analytics: true
52 }
53};
54
55// Modify nested properties ✅
56APP_CONFIG.features.payments = true;
57
58// Reassign variable ❌
59// APP_CONFIG = {}; // TypeError: Assignment to constant variableImmutability Patterns with const
While const doesn't make objects immutable, you can combine it with techniques like Object.freeze() and immutable update patterns to create truly immutable data structures.
1// Example 21: Object.freeze() for shallow immutability
2const frozenObject = Object.freeze({
3 name: "John",
4 age: 30,
5 address: {
6 city: "Boston",
7 state: "MA"
8 }
9});
10
11// frozenObject.age = 31; // ❌ Error in strict mode (silent fail in non-strict)
12// frozenObject.newProp = "value"; // ❌ Error in strict mode
13
14// Note: Object.freeze is shallow
15frozenObject.address.city = "Chicago"; // ✅ This still works!
16console.log(frozenObject.address.city); // "Chicago"
17
18// Example 22: Deep freeze function
19function deepFreeze(obj) {
20 Object.freeze(obj);
21 Object.getOwnPropertyNames(obj).forEach(prop => {
22 if (obj[prop] !== null &&
23 typeof obj[prop] === 'object' &&
24 !Object.isFrozen(obj[prop])) {
25 deepFreeze(obj[prop]);
26 }
27 });
28 return obj;
29}
30
31const deeplyFrozen = deepFreeze({
32 user: {
33 profile: {
34 name: "Alice",
35 settings: { theme: "dark" }
36 }
37 }
38});
39
40// deeplyFrozen.user.profile.settings.theme = "light"; // ❌ Now properly frozen
41
42// Example 23: Immutable update patterns
43const originalArray = [1, 2, 3];
44
45// Instead of modifying, create new arrays
46const newArray = [...originalArray, 4]; // [1, 2, 3, 4]
47const doubledArray = originalArray.map(x => x * 2); // [2, 4, 6]
48
49console.log(originalArray); // [1, 2, 3] - unchanged
50
51// Example 24: Immutable object updates
52const originalUser = { name: "John", age: 30 };
53
54// Create new objects instead of modifying
55const updatedUser = { ...originalUser, age: 31 };
56const userWithEmail = { ...originalUser, email: "john@example.com" };
57
58console.log(originalUser); // { name: "John", age: 30 } - unchanged
59console.log(updatedUser); // { name: "John", age: 31 }const Best Practices and Patterns
Following established best practices for const usage leads to more maintainable, predictable, and bug-resistant JavaScript code. Use const by default and only use let when reassignment is necessary.
1// Best Practice 1: Use const by default
2const DEFAULT_TIMEOUT = 5000;
3const API_BASE_URL = "https://api.example.com";
4const MAX_RETRY_ATTEMPTS = 3;
5
6// Only use let when you need reassignment
7let currentUser = null;
8let isLoading = false;
9let requestCount = 0;
10
11// Best Practice 2: Descriptive names for constants
12const TAX_RATE = 0.07; // GOOD
13const MAX_FILE_SIZE_BYTES = 10485760; // GOOD
14// const tr = 0.07; // BAD - unclear
15// const mfs = 10485760; // BAD - ambiguous
16
17// Best Practice 3: Group related constants
18const API_CONFIG = {
19 BASE_URL: "https://api.example.com",
20 TIMEOUT: 5000,
21 VERSION: "v1"
22};
23
24const ERROR_MESSAGES = {
25 NETWORK_ERROR: "Network connection failed",
26 AUTH_ERROR: "Authentication required",
27 VALIDATION_ERROR: "Invalid input data"
28};
29
30// Best Practice 4: Use const for function expressions
31const calculateTotal = (items) => {
32 const TAX = 0.07;
33 const subtotal = items.reduce((sum, item) => sum + item.price, 0);
34 return subtotal * (1 + TAX);
35};
36
37// Best Practice 5: const in modern JavaScript patterns
38const createUser = (userData) => {
39 const DEFAULT_SETTINGS = {
40 theme: "light",
41 notifications: true,
42 language: "en"
43 };
44
45 return {
46 ...userData,
47 settings: { ...DEFAULT_SETTINGS, ...userData.settings },
48 createdAt: new Date().toISOString()
49 };
50};
51
52// Best Practice 6: Avoid var in modern code
53// var oldVariable = "outdated"; // AVOID
54const modernVariable = "preferred"; // USE
55
56// Best Practice 7: Use const with destructuring
57const [first, second] = [1, 2, 3];
58const { name, age } = { name: "John", age: 30 };