JavaScript var Keyword Complete Guide

Understanding JavaScript var Keyword

The var keyword is the original way to declare variables in JavaScript, used before ES6 introduced let and const. While modern code prefers let and const, understanding var remains crucial for working with legacy codebases and understanding JavaScript's evolution. Variables declared with var are function-scoped, hoisted, and can be re-declared within the same scope.

Key Characteristics of var Keyword

  • Function Scoped - Variables are accessible throughout the entire function where they're declared
  • Hoisting - Variable declarations are moved to the top of their scope during compilation
  • Re-declaration - Can be declared multiple times in the same scope without errors
  • No Block Scope - Not limited to blocks like if statements or loops

Basic var Declaration Examples

Learn the fundamental ways to declare and use variables with var keyword. These examples demonstrate basic declaration, assignment, and initialization patterns that form the foundation of working with var.

javascript
1// Example 1: Basic variable declaration and assignment
2var userName = "John Smith";
3var userAge = 30;
4var isActive = true;
5
6console.log(userName);    // "John Smith"
7console.log(userAge);     // 30
8console.log(isActive);    // true
9
10// Example 2: Declaration without initialization
11var uninitializedVar;
12console.log(uninitializedVar); // undefined
13
14// Later assignment
15uninitializedVar = "Now I have a value";
16console.log(uninitializedVar); // "Now I have a value"
17
18// Example 3: Multiple variables in single statement
19var firstName = "John", lastName = "Doe", age = 25;
20console.log(firstName + " " + lastName); // "John Doe"
21
22// Example 4: Re-declaration allowed with var
23var counter = 10;
24console.log(counter); // 10
25
26var counter = 20;     // No error - re-declaration permitted
27console.log(counter); // 20

Declaration Patterns

  • Initialization - Variables can be declared and initialized in one statement
  • Separate Declaration - Can declare first, assign value later - initial value is undefined
  • Multiple Variables - Can declare multiple variables in single var statement
  • Re-declaration - Same variable can be declared multiple times in same scope

Function Scoping with var

Variables declared with var are function-scoped, meaning they are accessible throughout the entire function where they're declared, regardless of block boundaries. This differs from let and const which are block-scoped.

javascript
1// Example 5: Function scope demonstration
2function demonstrateFunctionScope() {
3    if (true) {
4        var functionScoped = "I'm accessible everywhere in this function";
5        console.log(functionScoped); // Works - "I'm accessible..."
6    }
7    
8    // Accessible outside the if block
9    console.log(functionScoped); // Still works - "I'm accessible..."
10}
11
12demonstrateFunctionScope();
13
14// Example 6: Global vs function scope
15var globalVariable = "I'm accessible everywhere";
16
17function testScopes() {
18    var localVariable = "I'm only available in this function";
19    console.log(globalVariable); // "I'm accessible everywhere"
20    console.log(localVariable);  // "I'm only available in this function"
21    
22    if (true) {
23        var blockVariable = "I'm not block-scoped";
24        console.log(blockVariable); // "I'm not block-scoped"
25    }
26    
27    console.log(blockVariable); // Still accessible - "I'm not block-scoped"
28}
29
30testScopes();
31console.log(globalVariable); // "I'm accessible everywhere"
32// console.log(localVariable); // Error: localVariable is not defined
33// console.log(blockVariable); // Error: blockVariable is not defined

Scoping Rules

  • Function Scope - Accessible anywhere within the declaring function
  • No Block Scope - Not confined to if blocks, for loops, or other block statements
  • Global Scope - If declared outside functions, becomes global variable
  • Scope Chain - Inner functions can access outer function's var variables

Hoisting Behavior of var

Hoisting is JavaScript's behavior of moving variable and function declarations to the top of their containing scope during the compilation phase. var declarations are hoisted but not their assignments.

javascript
1// Example 7: Basic hoisting demonstration
2console.log(hoistedVar); // undefined (not ReferenceError)
3var hoistedVar = "I was hoisted!";
4console.log(hoistedVar); // "I was hoisted!"
5
6// What JavaScript actually does:
7// var hoistedVar;          // Declaration hoisted to top
8// console.log(hoistedVar); // undefined
9// hoistedVar = "I was hoisted!"; // Assignment remains here
10// console.log(hoistedVar); // "I was hoisted!"
11
12// Example 8: Hoisting in function scope
13function hoistingExample() {
14    console.log(x); // undefined
15    var x = 10;
16    console.log(x); // 10
17}
18
19hoistingExample();
20
21// Example 9: Comparison with let (no hoisting initialization)
22// console.log(letVariable); // ReferenceError: Cannot access 'letVariable' before initialization
23// let letVariable = "I'm not hoisted like var";
24
25// Example 10: Multiple declarations hoisting
26var a = 1;
27function test() {
28    console.log(a); // undefined (not 1)
29    var a = 2;
30    console.log(a); // 2
31}
32test();

Re-declaration and Re-assignment

var allows both re-declaration and re-assignment within the same scope. This flexibility can be both useful and problematic, as it may lead to unintended variable overwrites.

javascript
1// Example 11: Re-declaration in same scope
2var count = 5;
3console.log(count); // 5
4
5var count = 10; // Re-declaration allowed
6console.log(count); // 10
7
8// Example 12: Re-assignment without re-declaration
9var price = 100;
10console.log(price); // 100
11
12price = 200; // Simple re-assignment
13console.log(price); // 200
14
15// Example 13: Re-declaration in different scopes
16var globalVar = "I'm global";
17
18function redeclareInFunction() {
19    var globalVar = "I'm local"; // This shadows the global variable
20    console.log(globalVar); // "I'm local"
21}
22
23redeclareInFunction();
24console.log(globalVar); // "I'm global" - global unchanged
25
26// Example 14: Accidental re-declaration
27var total = 0;
28// ... many lines of code ...
29var total = 100; // Accidental re-declaration - no error
30console.log(total); // 100 - original value lost

Common Patterns and Pitfalls

Understanding common patterns and potential pitfalls when using var helps write more robust code and avoid subtle bugs related to scoping and hoisting.

javascript
1// Example 15: Loop variable issue with closures
2var functions = [];
3for (var i = 0; i < 3; i++) {
4    functions.push(function() {
5        console.log(i); // All functions will log 3
6    });
7}
8
9functions[0](); // 3
10functions[1](); // 3
11functions[2](); // 3
12
13// Example 16: Solution using IIFE (Immediately Invoked Function Expression)
14var fixedFunctions = [];
15for (var i = 0; i < 3; i++) {
16    (function(j) {
17        fixedFunctions.push(function() {
18            console.log(j); // Will log 0, 1, 2 correctly
19        });
20    })(i);
21}
22
23fixedFunctions[0](); // 0
24fixedFunctions[1](); // 1
25fixedFunctions[2](); // 2
26
27// Example 17: Accidental global variable
28function createGlobal() {
29    accidentalGlobal = "I'm global"; // No var keyword
30    var properLocal = "I'm local";
31}
32
33createGlobal();
34console.log(accidentalGlobal); // "I'm global" - pollutes global scope
35// console.log(properLocal);   // Error - properly scoped
36
37// Example 18: Variable shadowing
38var x = "global";
39
40function shadowExample() {
41    console.log(x); // undefined (due to hoisting)
42    var x = "local";
43    console.log(x); // "local"
44}
45
46shadowExample();
47console.log(x); // "global"

var vs let vs const Comparison

Understanding the differences between var, let, and const helps in choosing the right tool for variable declaration and writing modern, maintainable JavaScript code.

javascript
1// Comparison in different scenarios
2
3// Scenario 1: Scope differences
4function scopeComparison() {
5    if (true) {
6        var varVariable = "I'm function scoped";
7        let letVariable = "I'm block scoped";
8        const constVariable = "I'm also block scoped";
9    }
10    
11    console.log(varVariable);   // "I'm function scoped" - accessible
12    // console.log(letVariable); // Error: letVariable is not defined
13    // console.log(constVariable); // Error: constVariable is not defined
14}
15scopeComparison();
16
17// Scenario 2: Hoisting differences
18console.log(varHoisted);    // undefined
19var varHoisted = "hoisted";
20
21// console.log(letHoisted); // ReferenceError: Cannot access 'letHoisted' before initialization
22// let letHoisted = "not hoisted";
23
24// Scenario 3: Re-declaration
25var redeclare = "first";
26var redeclare = "second"; // No error
27
28let noRedeclare = "first";
29// let noRedeclare = "second"; // SyntaxError: Identifier 'noRedeclare' has already been declared
30
31// Scenario 4: const requires initialization
32var canBeUndefined;
33let canAlsoBeUndefined;
34// const mustInitialize; // SyntaxError: Missing initializer in const declaration
35
36// Best practices summary:
37// Use const by default for variables that won't be reassigned
38// Use let when you need to reassign variables
39// Avoid var in new code - use only for legacy code maintenance

Best Practices and Legacy Code

While modern JavaScript development prefers let and const, understanding how to work with var is essential for maintaining legacy codebases and understanding older JavaScript patterns.

javascript
1// Good patterns when working with var
2
3// Pattern 1: Declare variables at top of function
4function goodVarUsage() {
5    // Declare all variables at top
6    var count = 0,
7        name = "John",
8        isActive = true;
9    
10    // Rest of the function logic
11    if (isActive) {
12        count++;
13        console.log(name + " is active");
14    }
15    
16    return count;
17}
18
19// Pattern 2: Use IIFE to create scope
20(function() {
21    var privateVar = "I'm private";
22    // This variable doesn't pollute global scope
23})();
24
25// Pattern 3: Be explicit about globals
26var app = app || {}; // Namespace pattern
27app.config = {
28    apiUrl: "https://api.example.com",
29    timeout: 5000
30};
31
32// Pattern 4: Avoid implicit globals
33function strictFunction() {
34    "use strict";
35    // accidentalGlobal = "error"; // Throws error in strict mode
36    var properLocal = "correct";
37}
38
39// When maintaining legacy code with var:
40// 1. Understand the existing scoping patterns
41// 2. Be cautious when refactoring var to let/const
42// 3. Watch for hoisting-related bugs
43// 4. Use linting tools to identify problematic var usage
44
45// Modern approach for new code:
46const PI = 3.14159;
47let counter = 0;
48// Avoid var in new development

JavaScript var Keyword FAQ

What is the main difference between var and let?

var is function-scoped and hoisted with initialization as undefined, while let is block-scoped and hoisted but not initialized (temporal dead zone). var allows re-declaration in the same scope, but let does not.

Why should I avoid using var in new code?

var's function scoping and hoisting behavior can lead to subtle bugs and harder-to-maintain code. let and const provide better scoping rules and prevent common errors like accidental re-declarations.

Can I still use var in modern JavaScript?

Yes, var still works in modern JavaScript for backward compatibility. However, it's recommended to use let and const in new code for better code quality and fewer bugs.

What is hoisting and how does it affect var?

Hoisting moves variable and function declarations to the top of their scope during compilation. var declarations are hoisted and initialized with undefined, which means you can access them before declaration (with value undefined) without errors.

Why do var variables in loops cause issues with closures?

Since var is function-scoped, all iterations of a loop share the same variable. When closures capture this variable, they all reference the final value after the loop completes, rather than the value at each iteration.

How can I fix loop closure issues with var?

Use Immediately Invoked Function Expressions (IIFE) to create a new scope for each iteration, or use let instead of var since let is block-scoped and creates a new binding for each iteration.

What happens if I declare the same var variable multiple times?

JavaScript allows re-declaring var variables in the same scope without errors. Subsequent declarations are effectively ignored, but any initialization in the re-declaration will overwrite the previous value.

When would I need to use var instead of let/const?

You might need to use var when maintaining legacy codebases, working with older libraries, or in specific edge cases where function scoping is desired. For new code, always prefer let and const.