Skip to content

Understanding JavaScript: const vs var

JavaScript const vs var

JavaScript, a versatile and widely-used programming language, offers different ways to declare variables. Among these, const and var are two fundamental keywords that serve distinct purposes. Understanding the differences between const and var is crucial for writing efficient, bug-free, and maintainable code. This guide delves into the nuances of const and var, highlighting their differences, use cases, and best practices.

Introduction

JavaScript provides multiple ways to declare variables, each with its own behavior and use cases. The evolution of JavaScript has introduced let and const, which offer block-scoping, enhancing code reliability and maintainability. However, understanding when and how to use var and const is essential, especially when working with legacy code or transitioning to modern JavaScript standards.

What is var?

The var keyword is one of the original ways to declare variables in JavaScript. It has been part of the language since its inception and has unique characteristics that differentiate it from let and const.

Scope

  • Function Scope: Variables declared with var are function-scoped, meaning they are accessible throughout the entire function in which they are declared.
  • Global Scope: If declared outside any function, a var variable becomes a global variable, attached to the window object in browsers.

Example:

function exampleVar() {
  if (true) {
    var x = 10;
    console.log(x); // Output: 10
  }
  console.log(x); // Output: 10 (Accessible outside the block)
}

exampleVar();
console.log(x); // ReferenceError: x is not defined

In the above example, x is accessible throughout the exampleVar function but not outside of it.

Hoisting

  • Hoisting Behavior: Variables declared with var are hoisted to the top of their enclosing scope. However, only the declaration is hoisted, not the initialization.
  • Undefined Initialization: Before the actual declaration line is executed, the variable exists and is initialized with undefined.

Example:

console.log(a); // Output: undefined
var a = 5;
console.log(a); // Output: 5

Here, the declaration var a is hoisted, but a is undefined until it’s assigned the value 5.

Re-declaration and Re-assignment

  • Re-declaration: Variables declared with var can be re-declared within the same scope without causing errors.
  • Re-assignment: Variables declared with var can be re-assigned to different values.
See also  How to Enable CSF on CyberPanel for Ubuntu 22.04: A Simple Step-by-Step Guide

Example:

var y = 10;
var y = 20; // Re-declaration is allowed
console.log(y); // Output: 20

y = 30; // Re-assignment is allowed
console.log(y); // Output: 30

What is const?

Introduced in ES6 (ECMAScript 2015), the const keyword allows the declaration of variables that cannot be re-assigned after their initial assignment. It promotes immutable references and block-scoping, enhancing code predictability and reducing bugs.

Scope

  • Block Scope: Variables declared with const are block-scoped, meaning they are accessible only within the nearest set of curly braces {} (e.g., inside a function, loop, or conditional statement).

Example:

function exampleConst() {
  if (true) {
    const z = 30;
    console.log(z); // Output: 30
  }
  console.log(z); // ReferenceError: z is not defined
}

exampleConst();

Hoisting

  • Hoisting Behavior: Like var, const variables are hoisted to the top of their block scope. However, they are not initialized and remain in a “temporal dead zone” until their declaration is encountered.
  • No Access Before Declaration: Attempting to access a const variable before its declaration results in a ReferenceError.

Example:

console.log(b); // ReferenceError: Cannot access 'b' before initialization
const b = 10;
console.log(b); // Output: 10

Re-declaration and Re-assignment

  • Re-declaration: Variables declared with const cannot be re-declared in the same scope.
  • Re-assignment: Variables declared with const cannot be re-assigned to different values.

Example:

const c = 40;
c = 50; // TypeError: Assignment to constant variable.

const c = 60; // SyntaxError: Identifier 'c' has already been declared

Immutability

  • Immutable Reference: While the binding is immutable, the value assigned to a const variable can be mutable (e.g., objects and arrays).
  • Deep Immutability Not Enforced: The properties of objects or elements of arrays declared with const can still be modified.

Example:

const obj = { name: "Alice" };
obj.name = "Bob"; // Allowed
console.log(obj.name); // Output: Bob

const arr = [1, 2, 3];
arr.push(4); // Allowed
console.log(arr); // Output: [1, 2, 3, 4]

However, attempting to reassign the entire object or array will result in an error:

obj = {}; // TypeError: Assignment to constant variable.
arr = []; // TypeError: Assignment to constant variable.

var vs const: Key Differences

Featurevarconst
ScopeFunction-scopedBlock-scoped
HoistingHoisted and initialized with undefinedHoisted but not initialized (Temporal Dead Zone)
Re-declarationAllowed within the same scopeNot allowed within the same scope
Re-assignmentAllowedNot allowed (binding is immutable)
ImmutabilityMutableImmutable binding, but value can be mutable (for objects and arrays)
Use CaseLegacy code, function-scoped variablesConstants, block-scoped variables, variables that should not be re-assigned
See also  Delay, Sleep, Pause & Wait in JavaScript

Summary of Differences

  1. Scope:
    • var is function-scoped.
    • const is block-scoped.
  2. Hoisting:
    • var declarations are hoisted and initialized with undefined.
    • const declarations are hoisted but remain uninitialized until their actual declaration, resulting in a ReferenceError if accessed before declaration.
  3. Re-declaration and Re-assignment:
    • var allows both re-declaration and re-assignment.
    • const prohibits both re-declaration and re-assignment, enforcing immutable bindings.
  4. Immutability:
    • var allows full mutability.
    • const enforces immutable bindings but allows mutations within mutable data structures like objects and arrays.

Best Practices

  1. Prefer const Over var:
    • Use const by default to ensure variable bindings remain constant, reducing potential bugs from accidental re-assignments.
  2. Use let When Re-assignment is Needed:
    • If a variable’s value needs to change, use let instead of var or const. let offers block-scoping without enforcing immutability.
  3. Avoid var Unless Necessary:
    • Modern JavaScript favors let and const for their clearer scoping rules. Reserve var for maintaining compatibility with older codebases.
  4. Define Variables in the Narrowest Scope Possible:
    • Limit the accessibility of variables to enhance code readability and maintainability. const and let facilitate this through block scoping.
  5. Use Descriptive Variable Names:
    • Regardless of the declaration keyword, meaningful variable names improve code clarity and reduce misunderstandings.

Common Mistakes

  1. Accessing const Before Declaration:
    • Attempting to access a const variable before its declaration will result in a ReferenceError due to the temporal dead zone.

    Incorrect:

    console.log(d); // ReferenceError
    const d = 100;
    
  2. Trying to Re-declare const Variables:
    • Re-declaring a const variable in the same scope causes a syntax error.

    Incorrect:

    const e = 200;
    const e = 300; // SyntaxError
    
  3. Expecting const to Imply Deep Immutability:
    • While const prevents re-assignment of the binding, it does not make the value itself immutable.

    Misconception:

    const arr = [1, 2, 3];
    arr.push(4); // Allowed, arr is now [1, 2, 3, 4]
    

    Solution: Use tools like Object.freeze() for shallow immutability or immutable data structures for deeper immutability.

  4. Overusing var Leading to Scope Confusion:
    • Since var is function-scoped, variables can unintentionally leak out of blocks, causing unpredictable behavior.

    Example:

    function testVar() {
      if (true) {
        var x = 10;
      }
      console.log(x); // Output: 10
    }
    testVar();
    

    This can lead to bugs if not carefully managed.

Conclusion

Understanding the distinctions between const and var in JavaScript is pivotal for writing clean, efficient, and error-free code. While var served its purpose in the early days of JavaScript, the introduction of const and let has provided developers with more robust tools for managing variable scope and immutability.

Key Takeaways:

  • Use const by Default: Opt for const to enforce immutable bindings, enhancing code reliability.
  • Embrace Block Scoping: Leverage the block-scoping capabilities of const and let to write predictable and maintainable code.
  • Reserve var for Specific Cases: Only use var when necessary, such as maintaining legacy code compatibility.

By adhering to these best practices and being mindful of common pitfalls, developers can harness the full potential of JavaScript’s variable declaration mechanisms, leading to more robust and scalable applications.

Additional Resources

Author