Comprehensive JavaScript Documentation
Table of Contents
1. Introduction
2. Getting Started
3. Variables and Data Types
4. Operators
5. Control Flow
6. Functions
7. Objects and Classes
8. Arrays
9. Error Handling
10. Asynchronous Programming
11. DOM Manipulation
12. Events
13. Modules
14. Advanced Concepts
15. Best Practices
Introduction
JavaScript is a high-level, interpreted programming language that is one of the core technologies of the
World Wide Web. Originally designed to make web pages interactive, JavaScript has evolved into a
versatile language used for server-side development, mobile applications, desktop applications, and
more.
Key Features
Dynamic typing: Variables don't need explicit type declarations
First-class functions: Functions can be assigned to variables, passed as arguments, and returned
from other functions
Prototype-based object orientation: Objects can inherit directly from other objects
Event-driven programming: Responds to user interactions and system events
Interpreted language: No compilation step required
Getting Started
Running JavaScript
JavaScript can be executed in several environments:
1. Browser Console: Open developer tools (F12) and use the console
2. HTML File: Include JavaScript in HTML using <script> tags
3. Node.js: Run JavaScript on the server or command line
4. Online IDEs: CodePen, JSFiddle, Repl.it
Basic Syntax
javascript
// Single-line comment
/* Multi-line
comment */
// Statements end with semicolons (optional but recommended)
console.log("Hello, World!");
// Case-sensitive language
let myVariable = "value";
let MyVariable = "different value"; // Different variable
Variables and Data Types
Variable Declarations
javascript
// var (function-scoped, can be redeclared)
var oldStyle = "avoid using var";
// let (block-scoped, cannot be redeclared)
let modernVariable = "prefer let";
// const (block-scoped, cannot be reassigned)
const CONSTANT = "unchangeable value";
Primitive Data Types
Number
javascript
let integer = 42;
let float = 3.14159;
let scientific = 2.5e6; // 2,500,000
let binary = 0b1010; // 10 in decimal
let octal = 0o755; // 493 in decimal
let hexadecimal = 0xFF; // 255 in decimal
// Special numeric values
let infinity = Infinity;
let negativeInfinity = -Infinity;
let notANumber = NaN;
// Number methods
Number.isInteger(42); // true
Number.parseFloat("3.14"); // 3.14
Number.parseInt("42px"); // 42
String
javascript
let singleQuotes = 'Hello';
let doubleQuotes = "World";
let templateLiteral = `Hello ${singleQuotes}!`;
// String methods
let text = "JavaScript";
text.length; // 10
text.toUpperCase(); // "JAVASCRIPT"
text.toLowerCase(); // "javascript"
text.charAt(0); // "J"
text.indexOf("Script"); // 4
text.slice(0, 4); // "Java"
text.substring(4, 10); // "Script"
text.replace("Java", "Type"); // "TypeScript"
text.split(""); // ["J", "a", "v", "a", "S", "c", "r", "i", "p", "t"]
Boolean
javascript
let isTrue = true;
let isFalse = false;
// Falsy values (evaluate to false)
false, 0, -0, 0n, "", null, undefined, NaN
// Truthy values (everything else)
true, 1, "0", "false", [ ], {}, function(){}
Null and Undefined
javascript
let nullValue = null; // Intentional absence of value
let undefinedValue; // Declared but not assigned
let explicitUndefined = undefined;
// Type checking
typeof null; // "object" (this is a known quirk)
typeof undefined; // "undefined"
Symbol
javascript
let sym1 = Symbol();
let sym2 = Symbol("description");
let sym3 = Symbol("description");
sym2 === sym3; // false (symbols are always unique)
BigInt
javascript
let bigNumber = 123456789012345678901234567890n;
let bigFromConstructor = BigInt("123456789012345678901234567890");
// Cannot mix BigInt with regular numbers
// bigNumber + 123; // TypeError
bigNumber + 123n; // Works
Non-Primitive Data Types
Objects
javascript
// Object literal
let person = {
name: "John",
age: 30,
city: "New York"
};
// Accessing properties
person.name; // "John"
person["age"]; // 30
// Adding properties
person.email = "[email protected]";
person["phone"] = "123-456-7890";
// Deleting properties
delete person.city;
Arrays
javascript
let numbers = [1, 2, 3, 4, 5];
let mixed = [1, "two", true, null, {name: "object"}];
// Array methods
numbers.length; // 5
numbers.push(6); // Adds to end
numbers.pop(); // Removes from end
numbers.unshift(0); // Adds to beginning
numbers.shift(); // Removes from beginning
numbers.indexOf(3); // 2
numbers.includes(4); // true
Operators
Arithmetic Operators
javascript
let a = 10, b = 3;
a + b; // 13 (addition)
a - b; // 7 (subtraction)
a * b; // 30 (multiplication)
a / b; // 3.333... (division)
a % b; // 1 (modulus/remainder)
a ** b; // 1000 (exponentiation)
// Increment and decrement
let x = 5;
x++; // x becomes 6 (post-increment)
++x; // x becomes 7 (pre-increment)
x--; // x becomes 6 (post-decrement)
--x; // x becomes 5 (pre-decrement)
Assignment Operators
javascript
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
javascript
let a = 5, b = "5";
a == b; // true (loose equality, type coercion)
a === b; // false (strict equality, no type coercion)
a != b; // false (loose inequality)
a !== b; // true (strict inequality)
a > 3; // true
a < 10; // true
a >= 5; // true
a <= 5; // true
Logical Operators
javascript
let x = true, y = false;
x && y; // false (AND)
x || y; // true (OR)
!x; // false (NOT)
// Short-circuit evaluation
let result = x && "This will execute";
let fallback = y || "Default value";
Bitwise Operators
javascript
let a = 5; // 101 in binary
let b = 3; // 011 in binary
a & b; // 1 (AND)
a | b; // 7 (OR)
a ^ b; // 6 (XOR)
~a; // -6 (NOT)
a << 1; // 10 (left shift)
a >> 1; // 2 (right shift)
a >>> 1; // 2 (unsigned right shift)
Control Flow
Conditional Statements
if...else
javascript
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
javascript
let day = "Monday";
switch (day) {
case "Monday":
console.log("Start of work week");
break;
case "Friday":
console.log("TGIF!");
break;
case "Saturday":
case "Sunday":
console.log("Weekend!");
break;
default:
console.log("Regular day");
}
Loops
for Loop
javascript
// Traditional for loop
for (let i = 0; i < 5; i++) {
console.log(i);
}
// for...in (iterates over object properties)
let obj = {a: 1, b: 2, c: 3};
for (let key in obj) {
console.log(key, obj[key]);
}
// for...of (iterates over iterable values)
let arr = [1, 2, 3, 4, 5];
for (let value of arr) {
console.log(value);
}
while Loop
javascript
let i = 0;
while (i < 5) {
console.log(i);
i++;
}
// do...while (executes at least once)
let j = 0;
do {
console.log(j);
j++;
} while (j < 5);
Loop Control
javascript
for (let i = 0; i < 10; i++) {
if (i === 3) continue; // Skip iteration
if (i === 7) break; // Exit loop
console.log(i);
}
Functions
Function Declarations
javascript
// Function declaration (hoisted)
function greet(name) {
return `Hello, ${name}!`;
}
// Function expression (not hoisted)
const greetExpression = function(name) {
return `Hello, ${name}!`;
};
// Arrow function (ES6+)
const greetArrow = (name) => `Hello, ${name}!`;
const greetArrowBlock = (name) => {
return `Hello, ${name}!`;
};
Parameters and Arguments
javascript
// Default parameters
function greet(name = "World") {
return `Hello, ${name}!`;
}
// Rest parameters
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
// Destructuring parameters
function createUser({name, age, email}) {
return {name, age, email, id: Math.random()};
}
// Spread syntax in function calls
const numbers = [1, 2, 3, 4, 5];
console.log(Math.max(...numbers));
Higher-Order Functions
javascript
// Function that takes another function as parameter
function operate(a, b, operation) {
return operation(a, b);
}
const add = (x, y) => x + y;
const multiply = (x, y) => x * y;
operate(5, 3, add); // 8
operate(5, 3, multiply); // 15
// Function that returns another function
function createMultiplier(factor) {
return function(number) {
return number * factor;
};
}
const double = createMultiplier(2);
double(5); // 10
Closures
javascript
function outerFunction(x) {
// Inner function has access to outer function's variables
function innerFunction(y) {
return x + y;
}
return innerFunction;
}
const addFive = outerFunction(5);
addFive(3); // 8
// Practical closure example
function createCounter() {
let count = 0;
return {
increment: () => ++count,
decrement: () => --count,
getValue: () => count
};
}
const counter = createCounter();
counter.increment(); // 1
counter.increment(); // 2
counter.getValue(); // 2
Objects and Classes
Object Creation
javascript
// Object literal
const person = {
name: "John",
age: 30,
greet: function() {
return `Hi, I'm ${this.name}`;
}
};
// Constructor function
function Person(name, age) {
this.name = name;
this.age = age;
this.greet = function() {
return `Hi, I'm ${this.name}`;
};
}
const john = new Person("John", 30);
// Object.create()
const personPrototype = {
greet: function() {
return `Hi, I'm ${this.name}`;
}
};
const mary = Object.create(personPrototype);
mary.name = "Mary";
mary.age = 25;
ES6 Classes
javascript
class Animal {
constructor(name, species) {
this.name = name;
this.species = species;
}
speak() {
return `${this.name} makes a sound`;
}
// Static method
static getClassName() {
return "Animal";
}
// Getter
get info() {
return `${this.name} is a ${this.species}`;
}
// Setter
set nickname(nick) {
this._nickname = nick;
}
}
// Inheritance
class Dog extends Animal {
constructor(name, breed) {
super(name, "dog");
this.breed = breed;
}
speak() {
return `${this.name} barks`;
}
fetch() {
return `${this.name} fetches the ball`;
}
}
const buddy = new Dog("Buddy", "Golden Retriever");
buddy.speak(); // "Buddy barks"
buddy.fetch(); // "Buddy fetches the ball"
Prototypes
javascript
// Adding methods to prototype
function Car(make, model) {
this.make = make;
this.model = model;
}
Car.prototype.start = function() {
return `${this.make} ${this.model} is starting`;
};
Car.prototype.stop = function() {
return `${this.make} ${this.model} has stopped`;
};
const myCar = new Car("Toyota", "Camry");
myCar.start(); // "Toyota Camry is starting"
// Prototype chain
console.log(myCar.__proto__ === Car.prototype); // true
console.log(Car.prototype.__proto__ === Object.prototype); // true
Object Methods
javascript
const obj = {a: 1, b: 2, c: 3};
// Object.keys() - returns array of keys
Object.keys(obj); // ["a", "b", "c"]
// Object.values() - returns array of values
Object.values(obj); // [1, 2, 3]
// Object.entries() - returns array of [key, value] pairs
Object.entries(obj); // [["a", 1], ["b", 2], ["c", 3]]
// Object.assign() - copies properties
const target = {a: 1};
const source = {b: 2, c: 3};
Object.assign(target, source); // {a: 1, b: 2, c: 3}
// Object.freeze() - prevents modifications
Object.freeze(obj);
// Object.hasOwnProperty()
obj.hasOwnProperty("a"); // true
Arrays
Array Creation and Basic Operations
javascript
// Array creation
const arr1 = [1, 2, 3, 4, 5];
const arr2 = new Array(5); // Creates array with 5 empty slots
const arr3 = Array.from("hello"); // ["h", "e", "l", "l", "o"]
const arr4 = Array.of(1, 2, 3); // [1, 2, 3]
// Basic operations
arr1.length; // 5
arr1[0]; // 1 (accessing element)
arr1[0] = 10; // Modifying element
Array Methods
Mutating Methods (modify original array)
javascript
let fruits = ["apple", "banana", "orange"];
// Adding elements
fruits.push("grape"); // Add to end
fruits.unshift("mango"); // Add to beginning
fruits.splice(2, 0, "kiwi"); // Insert at index 2
// Removing elements
fruits.pop(); // Remove from end
fruits.shift(); // Remove from beginning
fruits.splice(1, 1); // Remove 1 element at index 1
// Sorting and reversing
fruits.sort(); // Sort alphabetically
fruits.reverse(); // Reverse order
// Other mutating methods
fruits.fill("cherry", 1, 3); // Fill with value from index 1 to 3
Non-Mutating Methods (return new array)
javascript
const numbers = [1, 2, 3, 4, 5];
// map() - transform each element
const doubled = numbers.map(num => num * 2); // [2, 4, 6, 8, 10]
// filter() - filter elements based on condition
const evens = numbers.filter(num => num % 2 === 0); // [2, 4]
// reduce() - reduce to single value
const sum = numbers.reduce((acc, num) => acc + num, 0); // 15
// find() - find first matching element
const found = numbers.find(num => num > 3); // 4
// findIndex() - find index of first matching element
const index = numbers.findIndex(num => num > 3); // 3
// some() - check if at least one element matches
const hasEven = numbers.some(num => num % 2 === 0); // true
// every() - check if all elements match
const allPositive = numbers.every(num => num > 0); // true
// includes() - check if array contains value
const hasThree = numbers.includes(3); // true
// concat() - concatenate arrays
const moreNumbers = [6, 7, 8];
const combined = numbers.concat(moreNumbers); // [1, 2, 3, 4, 5, 6, 7, 8]
// slice() - extract portion of array
const portion = numbers.slice(1, 4); // [2, 3, 4]
// join() - join elements into string
const joined = numbers.join("-"); // "1-2-3-4-5"
Array Destructuring
javascript
const colors = ["red", "green", "blue", "yellow"];
// Basic destructuring
const [first, second] = colors; // first = "red", second = "green"
// Skip elements
const [, , third] = colors; // third = "blue"
// Rest elements
const [primary, ...secondary] = colors; // primary = "red", secondary = ["green", "blue", "yellow"]
// Default values
const [a, b, c, d, e = "purple"] = colors; // e = "purple" (default)
Error Handling
try...catch...finally
javascript
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 executes
console.log("Cleanup code");
}
Throwing Custom Errors
javascript
function divide(a, b) {
if (b === 0) {
throw new Error("Division by zero is not allowed");
}
return a / b;
}
// Custom error types
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}
function validateAge(age) {
if (age < 0 || age > 150) {
throw new ValidationError("Age must be between 0 and 150");
}
}
try {
validateAge(-5);
} catch (error) {
if (error instanceof ValidationError) {
console.log("Validation failed:", error.message);
} else {
console.log("Unexpected error:", error.message);
}
}
Asynchronous Programming
Callbacks
javascript
function fetchData(callback) {
setTimeout(() => {
const data = {id: 1, name: "John"};
callback(null, data);
}, 1000);
}
fetchData((error, data) => {
if (error) {
console.error(error);
} else {
console.log(data);
}
});
Promises
javascript
// Creating a promise
function fetchUserData(userId) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (userId > 0) {
resolve({id: userId, name: "John Doe"});
} else {
reject(new Error("Invalid user ID"));
}
}, 1000);
});
}
// Using promises
fetchUserData(1)
.then(user => {
console.log("User:", user);
return fetchUserData(2); // Chain another promise
})
.then(user => {
console.log("Second user:", user);
})
.catch(error => {
console.error("Error:", error.message);
})
.finally(() => {
console.log("Request completed");
});
// Promise methods
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);
Promise.all([promise1, promise2, promise3])
.then(values => console.log(values)); // [1, 2, 3]
Promise.race([promise1, promise2, promise3])
.then(value => console.log(value)); // 1 (first to resolve)
Promise.allSettled([promise1, promise2, promise3])
.then(results => console.log(results));
Async/Await
javascript
async function getUserData(userId) {
try {
const user = await fetchUserData(userId);
console.log("User:", user);
const posts = await fetchUserPosts(user.id);
console.log("Posts:", posts);
return {user, posts};
} catch (error) {
console.error("Error:", error.message);
throw error;
}
}
// Using async function
getUserData(1)
.then(result => console.log("Complete result:", result))
.catch(error => console.error("Failed:", error.message));
// Parallel execution with async/await
async function fetchMultipleUsers() {
try {
const [user1, user2, user3] = await Promise.all([
fetchUserData(1),
fetchUserData(2),
fetchUserData(3)
]);
return [user1, user2, user3];
} catch (error) {
console.error("Error fetching users:", error.message);
}
}
DOM Manipulation
Selecting Elements
javascript
// By ID
const element = document.getElementById("myId");
// By class name
const elements = document.getElementsByClassName("myClass");
// By tag name
const paragraphs = document.getElementsByTagName("p");
// Query selectors (CSS selectors)
const firstMatch = document.querySelector(".myClass");
const allMatches = document.querySelectorAll(".myClass");
// Advanced selectors
const specificElement = document.querySelector("div.container > p:first-child");
Modifying Elements
javascript
const element = document.getElementById("myElement");
// Content
element.textContent = "New text content";
element.innerHTML = "<strong>New HTML content</strong>";
// Attributes
element.setAttribute("class", "newClass");
element.getAttribute("class");
element.removeAttribute("class");
// Properties
element.id = "newId";
element.className = "newClass";
// Styles
element.style.color = "red";
element.style.backgroundColor = "yellow";
element.style.fontSize = "16px";
// CSS classes
element.classList.add("newClass");
element.classList.remove("oldClass");
element.classList.toggle("active");
element.classList.contains("myClass");
Creating and Inserting Elements
javascript
// Create new element
const newElement = document.createElement("div");
newElement.textContent = "Hello, World!";
newElement.className = "greeting";
// Insert into DOM
const container = document.getElementById("container");
container.appendChild(newElement);
container.insertBefore(newElement, container.firstChild);
// Insert adjacent HTML
element.insertAdjacentHTML("beforebegin", "<p>Before element</p>");
element.insertAdjacentHTML("afterbegin", "<p>First child</p>");
element.insertAdjacentHTML("beforeend", "<p>Last child</p>");
element.insertAdjacentHTML("afterend", "<p>After element</p>");
// Remove elements
element.remove();
parent.removeChild(element);
Events
Event Listeners
javascript
// Add event listener
const button = document.getElementById("myButton");
button.addEventListener("click", function(event) {
console.log("Button clicked!");
console.log("Event:", event);
});
// Arrow function event listener
button.addEventListener("click", (event) => {
event.preventDefault(); // Prevent default behavior
event.stopPropagation(); // Stop event bubbling
});
// Multiple events
function handleEvent(event) {
console.log(`${event.type} event occurred`);
}
button.addEventListener("mouseenter", handleEvent);
button.addEventListener("mouseleave", handleEvent);
// Remove event listener
button.removeEventListener("click", handleEvent);
Event Types
javascript
// Mouse events
element.addEventListener("click", handler);
element.addEventListener("dblclick", handler);
element.addEventListener("mousedown", handler);
element.addEventListener("mouseup", handler);
element.addEventListener("mousemove", handler);
element.addEventListener("mouseenter", handler);
element.addEventListener("mouseleave", handler);
// Keyboard events
document.addEventListener("keydown", (event) => {
console.log("Key pressed:", event.key);
console.log("Key code:", event.keyCode);
});
document.addEventListener("keyup", handler);
document.addEventListener("keypress", handler);
// Form events
form.addEventListener("submit", (event) => {
event.preventDefault();
// Handle form submission
});
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);
Event Delegation
javascript
// Instead of adding listeners to each item
const list = document.getElementById("myList");
list.addEventListener("click", (event) => {
if (event.target.tagName === "LI") {
console.log("List item clicked:", event.target.textContent);
}
});
// This works for dynamically added items too
const newItem = document.createElement("li");
newItem.textContent = "New item";
list.appendChild(newItem); // Click handler automatically works
Modules
ES6 Modules
Exporting
javascript
// math.js
export const PI = 3.14159;
export function add(a, b) {
return a + b;
}
export function multiply(a, b) {
return a * b;
}
// Default export
export default function subtract(a, b) {
return a - b;
}
// Alternative export syntax
const divide = (a, b) => a / b;
const power = (base, exponent) => base ** exponent;
export { divide, power };
Importing
javascript
// Importing named exports
import { add, multiply, PI } from './math.js';
// Importing default export
import subtract from './math.js';
// Importing all exports
import * as math from './math.js';
// Renaming imports
import { add as addition, multiply as multiplication } from './math.js';
// Mixed imports
import subtract, { add, multiply } from './math.js';
// Dynamic imports
async function loadMath() {
const math = await import('./math.js');
return math.add(2, 3);
}
CommonJS (Node.js)
javascript
// math.js
const PI = 3.14159;
function add(a, b) {
return a + b;
}
function multiply(a, b) {
return a * b;
}
module.exports = {
PI,
add,
multiply
};
// Using the module
const { add, multiply, PI } = require('./math');
const math = require('./math');
Advanced Concepts
Closures and Scope
javascript
// Lexical scoping
function outerFunction(x) {
const outerVariable = x;
function innerFunction(y) {
console.log(outerVariable + y);
}
return innerFunction;
}
const inner = outerFunction(10);
inner(5); // 15
// Module pattern using closures
const counterModule = (function() {
let count = 0;
return {
increment: function() {
count++;
return count;
},
decrement: function() {
count--;
return count;
},
getCount: function() {
return count;
}
};
})();
Hoisting
javascript
// Variable hoisting
console.log(x); // undefined (not ReferenceError)
var x = 5;
// Function hoisting
sayHello(); // "Hello!" (works because function is hoisted)
function sayHello() {
console.log("Hello!");
}
// let and const are not hoisted the same way
console.log(y); // ReferenceError
let y = 10;
This Keyword
javascript
// Global context
console.log(this); // Window object (in browser)
// Object method
const obj = {
name: "Object",
getName: function() {
return this.name;
}
};
obj.getName(); // "Object"
// Constructor function
function Person(name) {
this.name = name;
this.getName = function() {
return this.name;
};
}
const person = new Person("John");
person.getName(); // "John"
// Arrow functions (don't have their own 'this')
const obj2 = {
name: "Object2",
getName: () => {
return this.name; // 'this' refers to global object
}
};
// Explicit binding
function greet() {
console.log(`Hello, ${this.name}`);
}
const person1 = { name: "Alice" };
const person2 = { name: "Bob" };
greet.call(person1); // "Hello, Alice"
greet.apply(person2); // "Hello, Bob"
const boundGreet = greet.bind(person1);
boundGreet(); // "Hello, Alice"
Prototypal Inheritance
javascript
// Constructor function approach
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name