Back to course

Variables and Data Types

Content Reader1 words • 0:00 • Browser TTS

image.png

Variables and Data Types – The Building Blocks of JavaScript

Imagine you're organizing a massive library 📚. You need different types of containers for different kinds of items:

  • Boxes for books (strings of text)
  • Counting bins for inventory numbers (numbers)
  • Yes/No cards for availability (booleans)
  • Filing cabinets for complex records (objects)
  • Lists for catalogues (arrays)

In JavaScript, variables are your containers, and data types are the different kinds of items you can store in them. Understanding both is like learning the organizational system that makes your code library efficient and maintainable.

Variables: The Storage Containers 📦

Variables are named storage locations that hold data. Think of them as labeled boxes where you can store values and retrieve them later.

The Three Ways to Declare Variables

JavaScript gives you three keywords to create variables, each with different rules:

1. var – The Old-School Box 📦

var oldBox = "I'm from the past!";
var oldBox = "I can be redeclared!"; // This works (but is confusing)

function timeTravel() {
  var oldBox = "I'm function-scoped!";
  
  if (true) {
    var oldBox = "I ignore block boundaries!";
  }
  
  console.log(oldBox); // "I ignore block boundaries!"
}

var Characteristics:

  • Function-scoped (not block-scoped)
  • Hoisted and initialized with undefined
  • Can be redeclared in the same scope
  • Can be updated

2. let – The Modern Box 📦✨

let modernBox = "I'm the new standard!";
// let modernBox = "I can't be redeclared!"; // SyntaxError

if (true) {
  let modernBox = "I respect block scope!";
  console.log(modernBox); // "I respect block scope!"
}

console.log(modernBox); // "I'm the new standard!"

let Characteristics:

  • Block-scoped
  • Hoisted but in Temporal Dead Zone until declaration
  • Cannot be redeclared in the same scope
  • Can be updated

3. const – The Sealed Box 🔒

const sealedBox = "I never change!";
// sealedBox = "Trying to change"; // TypeError

const user = { name: "Alice", age: 25 };
user.age = 26; // This works! Object contents can change
user.city = "New York"; // This also works!

// user = {}; // This doesn't work! Can't reassign the variable

const Characteristics:

  • Block-scoped
  • Hoisted but in Temporal Dead Zone until declaration
  • Cannot be redeclared in the same scope
  • Cannot be reassigned (but object contents can be modified)

image.png

Naming Rules for Variables 🏷️

JavaScript variables must follow specific naming conventions:

// Valid variable names
let userName = "Alice";
let _private = "hidden";
let $element = document.getElementById('app');
let age2 = 25;
let myVeryLongVariableName = "descriptive";

// Invalid variable names
// let 2age = 25;        // Can't start with number
// let user-name = "Bob"; // Can't contain hyphens
// let let = "keyword";   // Can't use reserved keywords
// let my var = "space";  // Can't contain spaces

Best Practices for Naming:

  • Use camelCase for regular variables (userName, firstName)
  • Use UPPER_SNAKE_CASE for constants (MAX_USERS, API_URL)
  • Use descriptive names (userAge instead of a)
  • Avoid misleading names (temp for permanent data)

Data Types: What Goes in the Boxes? 🎁

JavaScript has 8 data types divided into two categories:

Primitive Types (The Basic Items) 🔧

Primitive types are immutable (cannot be changed) and stored by value.

1. Number 🔢

JavaScript has only one number type (unlike other languages that have int, float, etc.):

let integer = 42;
let decimal = 3.14159;
let negative = -17;
let scientific = 2.5e6; // 2.5 * 10^6 = 2,500,000

// Special number values
let infinity = Infinity;
let negInfinity = -Infinity;
let notANumber = NaN; // "Not a Number"

// Checking for special values
console.log(isFinite(42));     // true
console.log(isNaN(NaN));       // true
console.log(Number.isInteger(42)); // true

2. String 📝

Strings represent text data:

let singleQuotes = 'Hello, World!';
let doubleQuotes = "JavaScript is awesome!";
let templateLiteral = `The answer is ${40 + 2}`;

// String methods
let message = "JavaScript";
console.log(message.length);        // 10
console.log(message.toUpperCase()); // "JAVASCRIPT"
console.log(message.charAt(0));     // "J"
console.log(message.includes("Script")); // true

3. Boolean ✅❌

Represents logical true/false values:

let isActive = true;
let isComplete = false;

// Boolean conversion
console.log(Boolean(1));        // true
console.log(Boolean(0));        // false
console.log(Boolean("hello"));  // true
console.log(Boolean(""));       // false
console.log(Boolean(null));     // false
console.log(Boolean(undefined)); // false

4. Undefined 🤷‍♂️

Represents a variable that has been declared but not assigned:

let notAssigned;
console.log(notAssigned); // undefined

function noReturn() {
  // No return statement
}
console.log(noReturn()); // undefined

5. Null 🚫

Represents an intentional absence of value:

let intentionallyEmpty = null;
console.log(intentionallyEmpty); // null

// null vs undefined
console.log(null == undefined);  // true (loose equality)
console.log(null === undefined); // false (strict equality)

6. Symbol 🔣

Represents a unique identifier (ES6+):

let symbol1 = Symbol('description');
let symbol2 = Symbol('description');

console.log(symbol1 === symbol2); // false (always unique)

// Used for object property keys
const user = {
  [Symbol('id')]: 123,
  name: 'Alice'
};

7. BigInt 🔢+

For integers larger than Number.MAX_SAFE_INTEGER:

let bigNumber = 9007199254740991n; // Note the 'n' suffix
let anotherBig = BigInt(9007199254740991);

console.log(typeof bigNumber); // "bigint"

image.png

Reference Types (The Complex Containers) 🗃️

Reference types are mutable and stored by reference.

8. Object 🏢

Objects are collections of key-value pairs:

// Object literal
const person = {
  name: "Alice",
  age: 30,
  city: "New York",
  greet: function() {
    return `Hello, I'm ${this.name}!`;
  }
};

// Accessing properties
console.log(person.name);        // "Alice"
console.log(person["age"]);      // 30
console.log(person.greet());     // "Hello, I'm Alice!"

// Adding properties
person.email = "alice@example.com";
person["phone"] = "123-456-7890";

Special Object Types:

// Arrays
const fruits = ["apple", "banana", "orange"];
const numbers = [1, 2, 3, 4, 5];

// Functions
function calculateArea(length, width) {
  return length * width;
}

// Dates
const now = new Date();
const birthday = new Date("1990-05-15");

// Regular Expressions
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

image.png

Value vs Reference: The Storage Difference 📊

Understanding how JavaScript stores different types is crucial:

Primitives: Stored by Value 📋

let a = 5;
let b = a; // Copies the value

a = 10;
console.log(a); // 10
console.log(b); // 5 (unchanged)

Objects: Stored by Reference 🔗

let obj1 = { name: "Alice" };
let obj2 = obj1; // Copies the reference, not the object

obj1.name = "Bob";
console.log(obj1.name); // "Bob"
console.log(obj2.name); // "Bob" (both point to same object!)

// To copy an object, use spread operator or Object.assign
let obj3 = { ...obj1 }; // Shallow copy
obj1.name = "Charlie";
console.log(obj3.name); // "Bob" (obj3 is independent now)

image.png

Type Checking and Conversion 🔍

Checking Types with typeof

console.log(typeof 42);           // "number"
console.log(typeof "hello");      // "string"
console.log(typeof true);         // "boolean"
console.log(typeof undefined);    // "undefined"
console.log(typeof null);         // "object" (historical bug!)
console.log(typeof {});           // "object"
console.log(typeof []);           // "object"
console.log(typeof function(){}); // "function"

Better Type Checking

// More accurate object type checking
function getType(value) {
  return Object.prototype.toString.call(value).slice(8, -1);
}

console.log(getType([]));       // "Array"
console.log(getType(null));     // "Null"
console.log(getType(new Date)); // "Date"

Type Conversion (Coercion)

// Implicit conversion (automatic)
console.log("5" + 3);    // "53" (string concatenation)
console.log("5" - 3);    // 2 (numeric operation)
console.log("5" * "3");  // 15 (both converted to numbers)

// Explicit conversion (manual)
console.log(Number("123"));    // 123
console.log(String(123));      // "123"
console.log(Boolean(0));       // false
console.log(parseInt("123px")); // 123
console.log(parseFloat("3.14")); // 3.14

Practical Examples and Common Patterns

Example 1: User Data Management 👤

// Using const for objects that won't be reassigned
const user = {
  id: 1,
  name: "Alice Johnson",
  email: "alice@example.com",
  isActive: true,
  loginCount: 0,
  lastLogin: null
};

// Update user data (object contents can change)
user.loginCount++;
user.lastLogin = new Date();
user.preferences = { theme: "dark", language: "en" };

console.log(user);

Example 2: Configuration Management ⚙️

// Using const for configuration values
const CONFIG = {
  API_URL: "https://api.example.com",
  MAX_RETRIES: 3,
  TIMEOUT: 5000,
  FEATURES: {
    DARK_MODE: true,
    NOTIFICATIONS: false
  }
};

// Accessing configuration
function makeApiCall(endpoint) {
  const url = `${CONFIG.API_URL}/${endpoint}`;
  // Implementation here...
}

Example 3: Form Validation 📝

function validateUser(userData) {
  const errors = [];
  
  // Check required fields
  if (typeof userData.name !== 'string' || userData.name.trim() === '') {
    errors.push('Name is required and must be a string');
  }
  
  if (typeof userData.age !== 'number' || userData.age < 0) {
    errors.push('Age must be a positive number');
  }
  
  if (typeof userData.email !== 'string' || !userData.email.includes('@')) {
    errors.push('Valid email is required');
  }
  
  return {
    isValid: errors.length === 0,
    errors: errors
  };
}

// Usage
const result = validateUser({
  name: "Alice",
  age: 25,
  email: "alice@example.com"
});

console.log(result); // { isValid: true, errors: [] }

Best Practices for Variables and Data Types

1. Choose the Right Declaration Keyword 🎯

// Use const by default
const API_KEY = "your-api-key";
const users = [];

// Use let when you need to reassign
let currentUser = null;
let counter = 0;

// Avoid var in modern JavaScript
// var oldStyle = "avoid this";

2. Use Descriptive Variable Names 📛

// Good
const userAccountBalance = 1000;
const isEmailVerified = true;
const shoppingCartItems = [];

// Bad
const b = 1000;
const f = true;
const arr = [];
// Instead of separate variables
// const userName = "Alice";
// const userAge = 30;
// const userEmail = "alice@example.com";

// Use an object
const user = {
  name: "Alice",
  age: 30,
  email: "alice@example.com"
};

4. Handle Type Conversions Explicitly 🔄

// Be explicit about type conversions
const userInput = "123";
const userId = Number(userInput); // or parseInt(userInput, 10)

// Check for valid conversion
if (isNaN(userId)) {
  console.error("Invalid user ID provided");
}

Common Interview Questions & Answers

Q1: What's the difference between null and undefined?

let a; // undefined (declared but not assigned)
let b = null; // null (intentionally empty)

console.log(typeof a); // "undefined"
console.log(typeof b); // "object" (historical quirk)

console.log(a == b);  // true (loose equality)
console.log(a === b); // false (strict equality)

Q2: What will this code output?

let x = 1;
let y = x;
x = 2;
console.log(y); // ?

let obj1 = { value: 1 };
let obj2 = obj1;
obj1.value = 2;
console.log(obj2.value); // ?

Answer: 1 and 2. Primitives are copied by value, objects by reference.

Q3: Explain the difference between == and ===:

console.log(5 == "5");   // true (type coercion)
console.log(5 === "5");  // false (strict comparison)
console.log(null == undefined);  // true
console.log(null === undefined); // false

Summary

Variables (The Containers)

  • var: Function-scoped, hoisted, can be redeclared (avoid in modern JS)
  • let: Block-scoped, hoisted (TDZ), cannot be redeclared, can be updated
  • const: Block-scoped, hoisted (TDZ), cannot be redeclared or reassigned

Data Types (What Goes Inside)

Primitive Types (stored by value):

  1. Number: All numeric values
  2. String: Text data
  3. Boolean: true/false
  4. Undefined: Declared but not assigned
  5. Null: Intentionally empty
  6. Symbol: Unique identifiers
  7. BigInt: Large integers

Reference Types (stored by reference): 8. Object: Collections of key-value pairs (includes arrays, functions, dates, etc.)

Key Insights

  • Use const by default, let when you need reassignment, avoid var
  • Primitives are immutable and copied by value
  • Objects are mutable and copied by reference
  • Always use strict equality (===) unless you specifically need type coercion
  • Be explicit about type conversions to avoid unexpected behavior

My Personal Learning

Variables and data types are like the foundation of a house – you need to get them right before building anything complex. The biggest "aha!" moment for me was understanding value vs reference. Once I grasped that primitives and objects are stored differently, so many JavaScript behaviors started making sense!

The const keyword was initially confusing because you can still modify object contents. Think of const as saying "this variable will always point to the same box," but you can still change what's inside the box if it's an object.

Next Up

Now that you have a solid foundation with variables and data types, we'll explore Functions – the workhorses of JavaScript that let you organize and reuse your code effectively.

Remember: Master the basics, and everything else becomes easier! 🚀

Photo of Rahul Aher

Written by Rahul Aher

I'm Rahul, Sr. Software Engineer (SDE II) and passionate content creator. Sharing my expertise in software development to assist learners.

More about me