Overview

JavaScript is a dynamic, interpreted programming language that brings interactivity to web pages. It’s the programming language of the web, running in browsers, servers (Node.js), and many other environments.

Adding JavaScript to HTML

1. Inline JavaScript

<button onclick="alert('Hello!')">Click me</button>

2. Internal JavaScript

<script>
    console.log('Hello, World!');
</script>
<script src="script.js"></script>

Script Placement

<!DOCTYPE html>
<html>
<head>
    <!-- Scripts in head load before body content -->
    <script src="header-script.js"></script>
</head>
<body>
    <!-- Content here -->
    
    <!-- Scripts before closing body tag (recommended for DOM manipulation) -->
    <script src="main-script.js"></script>
</body>
</html>

Basic Syntax

Comments

// Single line comment
 
/* 
   Multi-line comment
   Spans multiple lines
*/
 
/**
 * JSDoc comment for documentation
 * @param {string} name - The name parameter
 */

Console Output

console.log('Hello, World!');       // Basic output
console.error('This is an error');  // Error message
console.warn('This is a warning');  // Warning message
console.table([{name: 'John', age: 30}]); // Table format

Statements and Semicolons

let name = 'John';    // Semicolon recommended
let age = 30          // Semicolon optional but recommended

Variables and Data Types

Variable Declarations

// var (function-scoped, avoid in modern JS)
var oldWay = 'function scoped';
 
// let (block-scoped, mutable)
let mutableVariable = 'can be changed';
mutableVariable = 'new value';
 
// const (block-scoped, immutable reference)
const immutableVariable = 'cannot be reassigned';
const obj = { name: 'John' };
obj.name = 'Jane'; // This is allowed (modifying object contents)
// obj = {}; // This would cause an error (reassigning)

Primitive Data Types

// String
let firstName = 'John';
let lastName = "Doe";
let template = `Hello, ${firstName} ${lastName}!`; // Template literals
 
// Number
let integer = 42;
let decimal = 3.14;
let negative = -10;
let infinity = Infinity;
let notANumber = NaN;
 
// Boolean
let isTrue = true;
let isFalse = false;
 
// Undefined
let undefinedVar;
console.log(undefinedVar); // undefined
 
// Null
let nullVar = null;
 
// Symbol (unique identifier)
let symbol = Symbol('description');
 
// BigInt (large integers)
let bigNumber = 123456789012345678901234567890n;

Type Checking

typeof 'hello';        // 'string'
typeof 42;             // 'number'
typeof true;           // 'boolean'
typeof undefined;      // 'undefined'
typeof null;           // 'object' (JavaScript quirk)
typeof {};             // 'object'
typeof [];             // 'object'
typeof function() {};  // 'function'
 
// Better array checking
Array.isArray([]);     // true
Array.isArray({});     // false

Operators

Arithmetic Operators

let a = 10;
let b = 3;
 
console.log(a + b);    // 13 (addition)
console.log(a - b);    // 7  (subtraction)
console.log(a * b);    // 30 (multiplication)
console.log(a / b);    // 3.333... (division)
console.log(a % b);    // 1  (modulus/remainder)
console.log(a ** b);   // 1000 (exponentiation)
 
// Increment/Decrement
let counter = 5;
counter++;             // 6 (post-increment)
++counter;             // 7 (pre-increment)
counter--;             // 6 (post-decrement)
--counter;             // 5 (pre-decrement)

Assignment Operators

let x = 10;
x += 5;    // x = x + 5  (15)
x -= 3;    // x = x - 3  (12)
x *= 2;    // x = x * 2  (24)
x /= 4;    // x = x / 4  (6)
x %= 4;    // x = x % 4  (2)
x **= 3;   // x = x ** 3 (8)

Comparison Operators

let a = 5;
let b = '5';
 
// Equality (loose - converts types)
console.log(a == b);   // true (5 == '5')
console.log(a != b);   // false
 
// Strict equality (no type conversion)
console.log(a === b);  // false (5 !== '5')
console.log(a !== b);  // true
 
// Relational
console.log(a > 3);    // true
console.log(a < 10);   // true
console.log(a >= 5);   // true
console.log(a <= 5);   // true

Logical Operators

let isAdult = true;
let hasLicense = false;
 
// AND (&&) - both must be true
console.log(isAdult && hasLicense); // false
 
// OR (||) - at least one must be true
console.log(isAdult || hasLicense); // true
 
// NOT (!) - inverts boolean value
console.log(!isAdult);              // false
console.log(!hasLicense);           // true
 
// Nullish coalescing (??) - returns right side if left is null/undefined
let name = null;
let defaultName = name ?? 'Guest';  // 'Guest'

Strings

String Methods

let text = 'Hello, World!';
 
// Length
console.log(text.length);           // 13
 
// Case conversion
console.log(text.toLowerCase());    // 'hello, world!'
console.log(text.toUpperCase());    // 'HELLO, WORLD!'
 
// Searching
console.log(text.indexOf('World')); // 7
console.log(text.includes('Hello')); // true
console.log(text.startsWith('Hello')); // true
console.log(text.endsWith('!')); // true
 
// Extracting
console.log(text.slice(0, 5));      // 'Hello'
console.log(text.substring(7, 12)); // 'World'
console.log(text.charAt(0));        // 'H'
 
// Modifying (returns new string)
console.log(text.replace('World', 'JavaScript')); // 'Hello, JavaScript!'
console.log(text.trim());           // Removes whitespace
console.log(text.split(', '));      // ['Hello', 'World!']

Template Literals

let name = 'John';
let age = 30;
 
// Multi-line strings
let multiLine = `
    This is a
    multi-line
    string
`;
 
// String interpolation
let greeting = `Hello, ${name}! You are ${age} years old.`;
 
// Expression evaluation
let calculation = `2 + 3 = ${2 + 3}`;
 
// Function calls
let formatted = `Today is ${new Date().toDateString()}`;

Arrays

Creating and Accessing Arrays

// Creating arrays
let fruits = ['apple', 'banana', 'orange'];
let numbers = [1, 2, 3, 4, 5];
let mixed = ['hello', 42, true, null];
let empty = [];
 
// Accessing elements
console.log(fruits[0]);        // 'apple'
console.log(fruits[1]);        // 'banana'
console.log(fruits[-1]);       // undefined (no negative indexing)
console.log(fruits.at(-1));    // 'orange' (ES2022 - gets last element)
 
// Array length
console.log(fruits.length);    // 3

Array Methods

Mutating Methods (change original array)

let fruits = ['apple', 'banana'];
 
// Adding elements
fruits.push('orange');         // ['apple', 'banana', 'orange']
fruits.unshift('grape');       // ['grape', 'apple', 'banana', 'orange']
 
// Removing elements
let last = fruits.pop();       // 'orange', array: ['grape', 'apple', 'banana']
let first = fruits.shift();    // 'grape', array: ['apple', 'banana']
 
// Modifying elements
fruits.splice(1, 1, 'kiwi');   // Remove 1 at index 1, add 'kiwi': ['apple', 'kiwi']
fruits.sort();                 // ['apple', 'kiwi'] (alphabetical sort)
fruits.reverse();              // ['kiwi', 'apple']

Non-mutating Methods (return new array/value)

let numbers = [1, 2, 3, 4, 5];
 
// Searching
console.log(numbers.indexOf(3));      // 2
console.log(numbers.includes(4));     // true
console.log(numbers.find(n => n > 3)); // 4
console.log(numbers.findIndex(n => n > 3)); // 3
 
// Transforming
let doubled = numbers.map(n => n * 2);     // [2, 4, 6, 8, 10]
let filtered = numbers.filter(n => n > 2); // [3, 4, 5]
let sum = numbers.reduce((acc, n) => acc + n, 0); // 15
 
// Other useful methods
let sliced = numbers.slice(1, 4);     // [2, 3, 4]
let joined = numbers.join(', ');      // '1, 2, 3, 4, 5'
let concatenated = numbers.concat([6, 7]); // [1, 2, 3, 4, 5, 6, 7]

Array Destructuring

let fruits = ['apple', 'banana', 'orange'];
 
// Basic destructuring
let [first, second, third] = fruits;
console.log(first);  // 'apple'
console.log(second); // 'banana'
 
// Skip elements
let [firstFruit, , thirdFruit] = fruits;
 
// Default values
let [a, b, c, d = 'grape'] = fruits;
console.log(d); // 'grape'
 
// Rest operator
let [head, ...tail] = fruits;
console.log(head); // 'apple'
console.log(tail); // ['banana', 'orange']

Objects

Creating Objects

// Object literal
let person = {
    name: 'John',
    age: 30,
    city: 'New York',
    isEmployed: true
};
 
// Constructor function
function Person(name, age) {
    this.name = name;
    this.age = age;
}
let john = new Person('John', 30);
 
// Object.create()
let personTemplate = {
    greet: function() {
        return `Hello, I'm ${this.name}`;
    }
};
let jane = Object.create(personTemplate);
jane.name = 'Jane';

Accessing Object Properties

let person = { name: 'John', age: 30, 'full-name': 'John Doe' };
 
// Dot notation
console.log(person.name);        // 'John'
person.age = 31;
 
// Bracket notation
console.log(person['name']);     // 'John'
console.log(person['full-name']); // 'John Doe'
 
// Dynamic property access
let property = 'age';
console.log(person[property]);   // 31
 
// Optional chaining (ES2020)
console.log(person.address?.street); // undefined (no error)

Object Methods

let person = {
    name: 'John',
    age: 30,
    greet: function() {
        return `Hello, I'm ${this.name}`;
    },
    // ES6 method shorthand
    sayAge() {
        return `I'm ${this.age} years old`;
    },
    // Arrow function (be careful with 'this')
    info: () => {
        // 'this' doesn't refer to the object in arrow functions
        return 'Person info';
    }
};
 
console.log(person.greet());   // 'Hello, I'm John'
console.log(person.sayAge());  // 'I'm 30 years old'

Object Destructuring

let person = { name: 'John', age: 30, city: 'New York' };
 
// Basic destructuring
let { name, age } = person;
console.log(name); // 'John'
console.log(age);  // 30
 
// Rename variables
let { name: fullName, age: years } = person;
console.log(fullName); // 'John'
 
// Default values
let { name, age, country = 'USA' } = person;
console.log(country); // 'USA'
 
// Rest operator
let { name, ...rest } = person;
console.log(rest); // { age: 30, city: 'New York' }

Useful Object Methods

let person = { name: 'John', age: 30, city: 'New York' };
 
// Get keys, values, entries
console.log(Object.keys(person));     // ['name', 'age', 'city']
console.log(Object.values(person));   // ['John', 30, 'New York']
console.log(Object.entries(person));  // [['name', 'John'], ['age', 30], ['city', 'New York']]
 
// Copy objects
let copy = Object.assign({}, person);  // Shallow copy
let copy2 = { ...person };             // Spread operator (ES6)
 
// Check properties
console.log('name' in person);         // true
console.log(person.hasOwnProperty('name')); // true
 
// Prevent modifications
Object.freeze(person);    // Makes object immutable
Object.seal(person);      // Prevents adding/removing properties

Functions

Function Declarations

// Function declaration (hoisted)
function greet(name) {
    return `Hello, ${name}!`;
}
 
// Function expression
const greet2 = function(name) {
    return `Hello, ${name}!`;
};
 
// Arrow function (ES6)
const greet3 = (name) => {
    return `Hello, ${name}!`;
};
 
// Arrow function shorthand
const greet4 = name => `Hello, ${name}!`;
const add = (a, b) => a + b;

Function Parameters

// Default parameters
function greet(name = 'Guest', greeting = 'Hello') {
    return `${greeting}, ${name}!`;
}
 
// Rest parameters
function sum(...numbers) {
    return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
 
// Destructured parameters
function createUser({ name, age, email }) {
    return { name, age, email, id: Date.now() };
}
createUser({ name: 'John', age: 30, email: 'john@example.com' });

Higher-Order Functions

// Function that returns a function
function createMultiplier(factor) {
    return function(number) {
        return number * factor;
    };
}
const double = createMultiplier(2);
console.log(double(5)); // 10
 
// Function that takes a function as parameter
function applyOperation(arr, operation) {
    return arr.map(operation);
}
const numbers = [1, 2, 3, 4];
const squared = applyOperation(numbers, x => x * x); // [1, 4, 9, 16]

Control Flow

Conditional Statements

// if...else
let age = 18;
 
if (age >= 18) {
    console.log('Adult');
} else if (age >= 13) {
    console.log('Teenager');
} else {
    console.log('Child');
}
 
// Ternary operator
let status = age >= 18 ? 'Adult' : 'Minor';
 
// Switch statement
let day = 'Monday';
switch (day) {
    case 'Monday':
    case 'Tuesday':
    case 'Wednesday':
    case 'Thursday':
    case 'Friday':
        console.log('Weekday');
        break;
    case 'Saturday':
    case 'Sunday':
        console.log('Weekend');
        break;
    default:
        console.log('Invalid day');
}

Loops

let fruits = ['apple', 'banana', 'orange'];
 
// for loop
for (let i = 0; i < fruits.length; i++) {
    console.log(fruits[i]);
}
 
// for...of loop (values)
for (let fruit of fruits) {
    console.log(fruit);
}
 
// for...in loop (keys/indices)
for (let index in fruits) {
    console.log(index, fruits[index]);
}
 
// while loop
let i = 0;
while (i < 3) {
    console.log(fruits[i]);
    i++;
}
 
// do...while loop
let j = 0;
do {
    console.log(fruits[j]);
    j++;
} while (j < 3);
 
// forEach method
fruits.forEach((fruit, index) => {
    console.log(`${index}: ${fruit}`);
});

Loop Control

for (let i = 0; i < 10; i++) {
    if (i === 3) {
        continue; // Skip iteration
    }
    if (i === 7) {
        break; // Exit loop
    }
    console.log(i);
}

DOM Manipulation

Selecting Elements

// Select by ID
const header = document.getElementById('header');
 
// Select by class (returns first match)
const button = document.querySelector('.btn');
 
// Select all by class
const buttons = document.querySelectorAll('.btn');
 
// Select by tag
const paragraphs = document.getElementsByTagName('p');
 
// Select by attribute
const required = document.querySelectorAll('[required]');
 
// CSS selectors
const firstParagraph = document.querySelector('p:first-child');
const navLinks = document.querySelectorAll('nav a');

Modifying Elements

const element = document.getElementById('myElement');
 
// Change content
element.textContent = 'New text content';
element.innerHTML = '<strong>New HTML content</strong>';
 
// Change attributes
element.setAttribute('class', 'new-class');
element.className = 'another-class';
element.id = 'newId';
 
// Change styles
element.style.color = 'red';
element.style.backgroundColor = 'yellow';
element.style.fontSize = '20px';
 
// Add/remove classes
element.classList.add('active');
element.classList.remove('inactive');
element.classList.toggle('visible');
element.classList.contains('active'); // true/false

Creating and Removing Elements

// Create elements
const newDiv = document.createElement('div');
newDiv.textContent = 'I am a new div';
newDiv.className = 'dynamic-content';
 
// Add to DOM
document.body.appendChild(newDiv);
document.body.insertBefore(newDiv, existingElement);
 
// Remove elements
const elementToRemove = document.getElementById('removeMe');
elementToRemove.remove(); // Modern way
// elementToRemove.parentNode.removeChild(elementToRemove); // Older way

Traversing the DOM

const element = document.getElementById('myElement');
 
// Parent
console.log(element.parentNode);
console.log(element.parentElement);
 
// Children
console.log(element.childNodes);        // Includes text nodes
console.log(element.children);          // Only element nodes
console.log(element.firstElementChild);
console.log(element.lastElementChild);
 
// Siblings
console.log(element.nextElementSibling);
console.log(element.previousElementSibling);

Events

Adding Event Listeners

const button = document.getElementById('myButton');
 
// Method 1: addEventListener (recommended)
button.addEventListener('click', function() {
    console.log('Button clicked!');
});
 
// Method 2: Arrow function
button.addEventListener('click', () => {
    console.log('Button clicked!');
});
 
// Method 3: Named function
function handleClick() {
    console.log('Button clicked!');
}
button.addEventListener('click', handleClick);
 
// Method 4: HTML attribute (not recommended)
// <button onclick="handleClick()">Click me</button>

Event Object

button.addEventListener('click', function(event) {
    console.log(event.type);        // 'click'
    console.log(event.target);      // The clicked element
    console.log(event.currentTarget); // The element with the listener
    
    event.preventDefault();  // Prevent default behavior
    event.stopPropagation(); // Stop event bubbling
});

Common Events

// Mouse events
element.addEventListener('click', handler);
element.addEventListener('dblclick', handler);
element.addEventListener('mousedown', handler);
element.addEventListener('mouseup', handler);
element.addEventListener('mouseover', handler);
element.addEventListener('mouseout', handler);
element.addEventListener('mousemove', handler);
 
// Keyboard events
element.addEventListener('keydown', handler);
element.addEventListener('keyup', handler);
element.addEventListener('keypress', handler); // Deprecated
 
// Form events
form.addEventListener('submit', handler);
input.addEventListener('change', handler);
input.addEventListener('input', handler);
input.addEventListener('focus', handler);
input.addEventListener('blur', handler);
 
// Window events
window.addEventListener('load', handler);
window.addEventListener('resize', handler);
window.addEventListener('scroll', handler);
document.addEventListener('DOMContentLoaded', handler);

Event Delegation

// Instead of adding listeners to many elements
document.getElementById('parent').addEventListener('click', function(event) {
    if (event.target.classList.contains('child-button')) {
        console.log('Child button clicked:', event.target.textContent);
    }
});

Asynchronous JavaScript

setTimeout and setInterval

// Execute once after delay
setTimeout(() => {
    console.log('This runs after 2 seconds');
}, 2000);
 
// Execute repeatedly
const intervalId = setInterval(() => {
    console.log('This runs every second');
}, 1000);
 
// Clear interval
clearInterval(intervalId);

Promises

// Creating a promise
const myPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
        const success = true;
        if (success) {
            resolve('Operation successful!');
        } else {
            reject('Operation failed!');
        }
    }, 1000);
});
 
// Using promises
myPromise
    .then(result => {
        console.log(result); // 'Operation successful!'
    })
    .catch(error => {
        console.error(error);
    })
    .finally(() => {
        console.log('Promise completed');
    });

Async/Await

// Async function
async function fetchData() {
    try {
        const response = await fetch('https://api.example.com/data');
        const data = await response.json();
        return data;
    } catch (error) {
        console.error('Error fetching data:', error);
        throw error;
    }
}
 
// Using async function
async function main() {
    try {
        const data = await fetchData();
        console.log(data);
    } catch (error) {
        console.error('Failed to get data:', error);
    }
}
 
main();

Fetch API

// GET request
fetch('https://api.example.com/users')
    .then(response => response.json())
    .then(users => console.log(users))
    .catch(error => console.error('Error:', error));
 
// POST request
fetch('https://api.example.com/users', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        name: 'John Doe',
        email: 'john@example.com'
    })
})
.then(response => response.json())
.then(result => console.log(result));
 
// With async/await
async function createUser(userData) {
    try {
        const response = await fetch('/api/users', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(userData)
        });
        
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        const result = await response.json();
        return result;
    } catch (error) {
        console.error('Error creating user:', error);
        throw error;
    }
}

ES6+ Modern Features

Template Literals

const name = 'John';
const age = 30;
 
// Multi-line strings
const message = `
    Hello ${name},
    You are ${age} years old.
    Welcome to our site!
`;
 
// Tagged template literals
function highlight(strings, ...values) {
    return strings.map((str, i) => {
        return str + (values[i] ? `<mark>${values[i]}</mark>` : '');
    }).join('');
}
 
const highlighted = highlight`Hello ${name}, you are ${age} years old!`;

Destructuring Assignment

// Array destructuring with default values and rest
const [first, second = 'default', ...rest] = [1, 2, 3, 4, 5];
 
// Object destructuring with renaming and defaults
const { name: fullName, age = 25, ...others } = { name: 'John', city: 'NYC' };
 
// Nested destructuring
const user = {
    id: 1,
    profile: {
        name: 'John',
        contact: { email: 'john@example.com' }
    }
};
const { profile: { name, contact: { email } } } = user;

Spread and Rest Operators

// Spread in arrays
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]
 
// Spread in objects
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const merged = { ...obj1, ...obj2 }; // { a: 1, b: 2, c: 3, d: 4 }
 
// Rest in function parameters
function sum(...numbers) {
    return numbers.reduce((total, num) => total + num, 0);
}

Classes

class Person {
    // Constructor
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    
    // Method
    greet() {
        return `Hello, I'm ${this.name}`;
    }
    
    // Getter
    get info() {
        return `${this.name} is ${this.age} years old`;
    }
    
    // Setter
    set age(newAge) {
        if (newAge > 0) {
            this._age = newAge;
        }
    }
    
    // Static method
    static species() {
        return 'Homo sapiens';
    }
}
 
// Inheritance
class Student extends Person {
    constructor(name, age, school) {
        super(name, age); // Call parent constructor
        this.school = school;
    }
    
    greet() {
        return `${super.greet()}, I study at ${this.school}`;
    }
}
 
const john = new Person('John', 30);
const jane = new Student('Jane', 20, 'MIT');

Modules (ES6 Modules)

// math.js - Export
export const PI = 3.14159;
 
export function add(a, b) {
    return a + b;
}
 
export default function multiply(a, b) {
    return a * b;
}
 
// main.js - Import
import multiply, { PI, add } from './math.js';
import * as math from './math.js';
 
console.log(add(2, 3));        // 5
console.log(multiply(4, 5));   // 20
console.log(math.PI);          // 3.14159

Map and Set

// Map
const userRoles = new Map();
userRoles.set('john', 'admin');
userRoles.set('jane', 'user');
 
console.log(userRoles.get('john')); // 'admin'
console.log(userRoles.has('jane')); // true
console.log(userRoles.size);        // 2
 
// Iterate over Map
for (let [user, role] of userRoles) {
    console.log(`${user}: ${role}`);
}
 
// Set
const uniqueNumbers = new Set([1, 2, 3, 3, 4, 4, 5]);
console.log(uniqueNumbers); // Set { 1, 2, 3, 4, 5 }
 
uniqueNumbers.add(6);
uniqueNumbers.delete(1);
console.log(uniqueNumbers.has(3)); // true

Error Handling

Try…Catch…Finally

try {
    // Code that might throw an error
    let result = riskyOperation();
    console.log(result);
} catch (error) {
    // Handle the error
    console.error('An error occurred:', error.message);
} finally {
    // Always runs (optional)
    console.log('Cleanup operations');
}

Custom Errors

class CustomError extends Error {
    constructor(message) {
        super(message);
        this.name = 'CustomError';
    }
}
 
function validateAge(age) {
    if (age < 0) {
        throw new CustomError('Age cannot be negative');
    }
    if (age > 150) {
        throw new CustomError('Age seems unrealistic');
    }
    return true;
}
 
try {
    validateAge(-5);
} catch (error) {
    if (error instanceof CustomError) {
        console.log('Validation error:', error.message);
    } else {
        console.log('Unexpected error:', error);
    }
}

Common Patterns and Best Practices

IIFE (Immediately Invoked Function Expression)

// Avoid global pollution
(function() {
    // Private scope
    let privateVariable = 'secret';
    
    // Public interface
    window.MyModule = {
        publicMethod: function() {
            return privateVariable;
        }
    };
})();

Module Pattern

const Calculator = (function() {
    // Private variables and functions
    let result = 0;
    
    function add(x) {
        result += x;
        return this;
    }
    
    function multiply(x) {
        result *= x;
        return this;
    }
    
    function getResult() {
        return result;
    }
    
    function reset() {
        result = 0;
        return this;
    }
    
    // Public API
    return {
        add,
        multiply,
        getResult,
        reset
    };
})();
 
// Usage: Calculator.add(5).multiply(2).getResult(); // 10

Debouncing and Throttling

// Debounce - execute after delay, reset timer on new calls
function debounce(func, delay) {
    let timeoutId;
    return function(...args) {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(() => func.apply(this, args), delay);
    };
}
 
// Throttle - execute at most once per interval
function throttle(func, interval) {
    let lastTime = 0;
    return function(...args) {
        const now = Date.now();
        if (now - lastTime >= interval) {
            lastTime = now;
            func.apply(this, args);
        }
    };
}
 
// Usage
const debouncedSearch = debounce(searchFunction, 300);
const throttledScroll = throttle(scrollHandler, 100);
 
document.getElementById('search').addEventListener('input', debouncedSearch);
window.addEventListener('scroll', throttledScroll);

Quick Reference Cheat Sheet

Data Types

// Primitives
string, number, boolean, undefined, null, symbol, bigint
 
// Objects
{}, [], function() {}, Date, RegExp, Map, Set

Array Methods Quick Reference

// Mutating
push(), pop(), shift(), unshift(), splice(), sort(), reverse()
 
// Non-mutating
map(), filter(), reduce(), find(), slice(), concat(), join()
 
// Testing
includes(), some(), every(), indexOf(), findIndex()

Object Methods Quick Reference

Object.keys(), Object.values(), Object.entries()
Object.assign(), Object.freeze(), Object.seal()
hasOwnProperty(), Object.hasOwn() // ES2022

DOM Selection Quick Reference

document.getElementById('id')
document.querySelector('.class')
document.querySelectorAll('tag')
element.parentElement, element.children
element.nextElementSibling, element.previousElementSibling

Event Handling Quick Reference

element.addEventListener('event', handler)
event.preventDefault(), event.stopPropagation()
event.target, event.currentTarget

Async Patterns

// Promise
promise.then().catch().finally()
 
// Async/Await
async function() { await promise; }
 
// Fetch
fetch(url).then(res => res.json())

Best Practices

🎯 Code Quality

  • Use const by default, let when reassignment needed, avoid var
  • Use meaningful variable and function names
  • Keep functions small and focused on one task
  • Use semicolons consistently
  • Use strict equality (===) instead of loose equality (==)

🚀 Performance

  • Minimize DOM manipulation in loops
  • Use event delegation for dynamic content
  • Debounce/throttle event handlers for scroll, resize, input
  • Use const and let for better optimization
  • Avoid memory leaks (remove event listeners, clear timers)

♿ Accessibility

  • Use semantic HTML with JavaScript
  • Ensure keyboard navigation works
  • Provide meaningful error messages
  • Test with screen readers
  • Don’t rely solely on JavaScript for critical functionality

🔧 Modern JavaScript

  • Use ES6+ features when appropriate
  • Prefer async/await over Promises for readability
  • Use template literals instead of string concatenation
  • Leverage destructuring and spread operators
  • Use modules to organize code

Common Mistakes to Avoid

Don’t:

  • Use var in modern JavaScript
  • Forget to handle errors in async operations
  • Manipulate DOM extensively in loops
  • Use global variables unnecessarily
  • Compare with == instead of ===
  • Forget to remove event listeners when cleaning up
  • Use innerHTML with untrusted content (XSS risk)

Do:

  • Use const and let appropriately
  • Handle errors properly with try/catch
  • Use modern array methods (map, filter, reduce)
  • Validate user input
  • Use meaningful variable names
  • Comment complex logic
  • Test your code thoroughly

Last Updated: 2025-07-22