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>
3. External JavaScript (Recommended)
<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, avoidvar
- 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
andlet
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
andlet
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
Related Notes
- HTML Crash Course & Cheat Sheet
- CSS Fundamentals Guide & Reference
- DOM Manipulation Deep Dive
- Asynchronous JavaScript Mastery
- JavaScript ES6+ Features
- Web APIs and Browser Features
- JavaScript Testing Fundamentals
Last Updated: 2025-07-22