JavaScript Basics

First JavaScript Program

// Simple Hello World program
console.log("Hello, World!");

// In HTML file
<script>
alert("Hello, World!");
</script>

// External JavaScript file
<script src="script.js" defer></script>
Note: JavaScript can be included directly in HTML or in external files.

Data Types & Variables

// Primitive data types
let age = 25; // Number
let name = "John Doe"; // String
let isJavaScriptFun = true; // Boolean
let nothing = null; // Null
let notDefined; // Undefined
let id = Symbol("id"); // Symbol (ES6)
let bigNumber = 12345678901234567890n; // BigInt (ES2020)

// Reference data types
let person = { // Object
name: "John",
age: 30
};

let colors = ["red", "green", "blue"]; // Array

// Variable declarations
var oldVariable = "avoid using var"; // Function scoped
let changeable = "can be changed"; // Block scoped
const constantValue = "cannot be reassigned"; // Block scoped

Operators

// Arithmetic operators
let a = 10, b = 3;
let sum = a + b; // 13
let diff = a - b; // 7
let product = a * b; // 30
let quotient = a / b; // 3.333...
let remainder = a % b; // 1
let exponent = a ** b; // 1000 (10^3)

// Comparison operators
let result = (a == b); // false (loose equality)
result = (a === b); // false (strict equality)
result = (a != b); // true
result = (a !== b); // true
result = (a > b); // true

// Logical operators
let x = true, y = false;
result = (x && y); // false
result = (x || y); // true
result = !x; // false

// Assignment operators
a += 5; // equivalent to a = a + 5
b *= 2; // equivalent to b = b * 2

Type Conversion

// String to Number
let str = "123";
let num = Number(str); // 123 (number)
num = parseInt(str); // 123 (integer)
num = parseFloat("123.45"); // 123.45 (float)

// Number to String
let number = 456;
let string = String(number); // "456"
string = number.toString(); // "456"
string = 123 + ""; // "123" (using concatenation)

// Boolean conversion
let truthyValue = Boolean(1); // true
let falsyValue = Boolean(0); // false

// Falsy values in JavaScript
// false, 0, "", null, undefined, NaN

// Truthy values
// Everything else, including "0", "false", [], {}

Strings

String Methods

let str = "Hello, World!";

// Basic string methods
let length = str.length; // 13
let upper = str.toUpperCase(); // "HELLO, WORLD!"
let lower = str.toLowerCase(); // "hello, world!"
let sub = str.substring(0, 5); // "Hello"
let replaced = str.replace("World", "JavaScript"); // "Hello, JavaScript!"

// Searching in strings
let index = str.indexOf("World"); // 7
let lastIndex = str.lastIndexOf("l"); // 10
let includes = str.includes("Hello"); // true
let startsWith = str.startsWith("Hello"); // true
let endsWith = str.endsWith("!"); // true

// Splitting and joining
let parts = str.split(", "); // ["Hello", "World!"]
let joined = parts.join(" - "); // "Hello - World!"

// Trimming whitespace
let withSpaces = " Hello ";
let trimmed = withSpaces.trim(); // "Hello"
let trimStart = withSpaces.trimStart(); // "Hello "
let trimEnd = withSpaces.trimEnd(); // " Hello"

Template Literals

// Basic template literals
let name = "John";
let age = 30;

// String interpolation
let message = `Hello, my name is ${name} and I am ${age} years old.`;
// "Hello, my name is John and I am 30 years old."

// Multi-line strings
let multiLine = `This is a
multi-line
string.`
;

// Expressions in template literals
let a = 5;
let b = 10;
let calculation = `The sum of ${a} and ${b} is ${a + b}.`;
// "The sum of 5 and 10 is 15."

// Tagged templates
function tag(strings, ...values) {
return strings.reduce((result, string, i) => {
return result + string + (values[i] || "");
}, "");
}

let tagged = tag`Hello ${name}!`; // "Hello John!"

Arrays

Array Methods

let fruits = ["Apple", "Banana"];

// Adding/removing elements
fruits.push("Orange"); // Add to end: ["Apple", "Banana", "Orange"]
let last = fruits.pop(); // Remove from end: "Orange"
fruits.unshift("Strawberry"); // Add to start: ["Strawberry", "Apple", "Banana"]
let first = fruits.shift(); // Remove from start: "Strawberry"

// Finding elements
let index = fruits.indexOf("Banana"); // 1
let includes = fruits.includes("Apple"); // true
let found = fruits.find(fruit => fruit.startsWith("B")); // "Banana"

// Transforming arrays
let upperFruits = fruits.map(fruit => fruit.toUpperCase()); // ["APPLE", "BANANA"]
let filtered = fruits.filter(fruit => fruit.length > 5); // ["Banana"]
let sum = [1, 2, 3].reduce((total, num) => total + num, 0); // 6

// Other useful methods
let sliced = fruits.slice(1); // ["Banana"] (copy from index 1)
fruits.splice(1, 1, "Mango"); // Remove 1 element at index 1, add "Mango"
let combined = fruits.concat(["Grape", "Kiwi"]); // New combined array
fruits.sort(); // Sort alphabetically
fruits.reverse(); // Reverse the array

Array Iteration

let numbers = [1, 2, 3, 4, 5];

// forEach - execute function for each element
numbers.forEach((num, index) => {
console.log(`Index ${index}: ${num}`);
});

// map - create new array by transforming each element
let squares = numbers.map(num => num * num); // [1, 4, 9, 16, 25]

// filter - create new array with elements that pass test
let evens = numbers.filter(num => num % 2 === 0); // [2, 4]

// reduce - reduce array to single value
let sum = numbers.reduce((total, num) => total + num, 0); // 15

// some - test if at least one element passes test
let hasEven = numbers.some(num => num % 2 === 0); // true

// every - test if all elements pass test
let allPositive = numbers.every(num => num > 0); // true

// find - find first element that passes test
let firstEven = numbers.find(num => num % 2 === 0); // 2

// findIndex - find index of first element that passes test
let firstEvenIndex = numbers.findIndex(num => num % 2 === 0); // 1

Dates

Date Creation

// Current date and time
let now = new Date();
console.log(now); // e.g., "Mon Dec 04 2023 14:30:45 GMT+0530 (IST)"

// Specific date
let date1 = new Date("2023-12-25"); // Christmas 2023
let date2 = new Date(2023, 11, 25); // Month is 0-indexed (11 = December)
let date3 = new Date(2023, 11, 25, 10, 30, 0); // With time

// Timestamp (milliseconds since Jan 1, 1970)
let timestamp = new Date().getTime();
let dateFromTimestamp = new Date(1701683456789);

// Date parsing
let parsedDate = Date.parse("2023-12-25"); // Returns timestamp

// Invalid date
let invalidDate = new Date("invalid");
console.log(isNaN(invalidDate.getTime())); // true

Date Methods

let date = new Date();

// Get date components
let year = date.getFullYear(); // 2023
let month = date.getMonth(); // 0-11 (0 = January)
let day = date.getDate(); // 1-31
let weekday = date.getDay(); // 0-6 (0 = Sunday)
let hours = date.getHours(); // 0-23
let minutes = date.getMinutes(); // 0-59
let seconds = date.getSeconds(); // 0-59
let milliseconds = date.getMilliseconds(); // 0-999

// Set date components
date.setFullYear(2024);
date.setMonth(0); // January
date.setDate(1);
date.setHours(12);
date.setMinutes(0);
date.setSeconds(0);

// Date formatting
let dateString = date.toDateString(); // "Mon Dec 04 2023"
let timeString = date.toTimeString(); // "14:30:45 GMT+0530 (IST)"
let localeString = date.toLocaleString(); // "12/4/2023, 2:30:45 PM"
let isoString = date.toISOString(); // "2023-12-04T09:00:45.000Z"

// Date arithmetic
let today = new Date();
let tomorrow = new Date(today);
tomorrow.setDate(today.getDate() + 1);

// Date difference in days
let diffTime = tomorrow - today;
let diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); // 1

Math

Math Properties & Methods

// Math properties (constants)
let pi = Math.PI; // 3.141592653589793
let e = Math.E; // 2.718281828459045
let sqrt2 = Math.SQRT2; // 1.4142135623730951
let ln2 = Math.LN2; // 0.6931471805599453

// Rounding methods
Math.round(4.7); // 5
Math.round(4.4); // 4
Math.ceil(4.2); // 5
Math.floor(4.9); // 4
Math.trunc(4.9); // 4 (removes fractional part)

// Other math methods
Math.abs(-4.7); // 4.7 (absolute value)
Math.sqrt(64); // 8 (square root)
Math.cbrt(64); // 4 (cube root)
Math.pow(8, 2); // 64 (8 to the power of 2)
Math.min(0, 150, 30, 20, -8); // -8
Math.max(0, 150, 30, 20, -8); // 150
Math.random(); // Random number between 0 (inclusive) and 1 (exclusive)

// Trigonometric methods
Math.sin(90 * Math.PI / 180); // 1 (sine of 90 degrees)
Math.cos(0 * Math.PI / 180); // 1 (cosine of 0 degrees)
Math.tan(45 * Math.PI / 180); // 1 (tangent of 45 degrees)

// Logarithmic methods
Math.log(10); // 2.302585092994046 (natural logarithm)
Math.log10(100); // 2 (base 10 logarithm)
Math.log2(8); // 3 (base 2 logarithm)

Random Numbers

// Random number between 0 (inclusive) and 1 (exclusive)
let randomNum = Math.random();

// Random integer between min and max (inclusive)
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}

// Examples
let diceRoll = getRandomInt(1, 6); // Random number between 1-6
let randomPercent = Math.random() * 100; // Random percentage 0-100

// Random array element
let colors = ["red", "green", "blue", "yellow"];
let randomColor = colors[Math.floor(Math.random() * colors.length)];

// Random boolean
let randomBool = Math.random() >= 0.5; // true or false

// Seeded random (not cryptographically secure)
function seededRandom(seed) {
seed = Math.sin(seed) * 10000;
return seed - Math.floor(seed);
}

// Cryptographically secure random (for security purposes)
let cryptoArray = new Uint32Array(1);
window.crypto.getRandomValues(cryptoArray);
let secureRandom = cryptoArray[0] / (0xFFFFFFFF + 1);

Classes

Class Basics

// Class declaration
class Person {
// Constructor
constructor(name, age) {
// Properties
this.name = name;
this.age = age;
}

// Method
greet() {
return `Hello, my name is ${this.name}`;
}

// Static method
static compareAges(person1, person2) {
return person1.age - person2.age;
}
}

// Creating instances
let person1 = new Person("Alice", 30);
let person2 = new Person("Bob", 25);

// Using methods
console.log(person1.greet()); // "Hello, my name is Alice"

// Using static method
let ageDifference = Person.compareAges(person1, person2); // 5

// Getter and setter
class Rectangle {
constructor(width, height) {
this.width = width;
this.height = height;
}

// Getter
get area() {
return this.width * this.height;
}

// Setter
set area(value) {
this.width = Math.sqrt(value);
this.height = Math.sqrt(value);
}
}

let rect = new Rectangle(10, 5);
console.log(rect.area); // 50
rect.area = 100; // Sets width and height to 10

Inheritance

// Base class
class Animal {
constructor(name) {
this.name = name;
}

speak() {
console.log(`${this.name} makes a noise.`);
}
}

// Derived class
class Dog extends Animal {
constructor(name, breed) {
super(name); // Call the parent constructor
this.breed = breed;
}

// Method overriding
speak() {
console.log(`${this.name} barks.`);
}

// New method
fetch() {
console.log(`${this.name} fetches the ball!`);
}
}

// Using inheritance
let animal = new Animal("Generic Animal");
let dog = new Dog("Rex", "German Shepherd");

animal.speak(); // "Generic Animal makes a noise."
dog.speak(); // "Rex barks."
dog.fetch(); // "Rex fetches the ball!"

// instanceof operator
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true
console.log(animal instanceof Dog); // false

// Mixins (alternative to multiple inheritance)
let canSwim = {
swim() {
console.log(`${this.name} swims.`);
}
};

// Assign mixin to class prototype
Object.assign(Dog.prototype, canSwim);
dog.swim(); // "Rex swims."

Sets & Maps

Sets

// Creating Sets
let set = new Set();

// Adding values
set.add(1);
set.add(2);
set.add(3);
set.add(2); // Duplicate, won't be added

// Creating Set from array
let array = [1, 2, 3, 4, 4, 5];
let setFromArray = new Set(array); // Set(5) {1, 2, 3, 4, 5}

// Set properties and methods
set.size; // Number of elements
set.has(1); // true
set.delete(2); // Remove element
set.clear(); // Remove all elements

// Iterating Sets
for (let item of set) {
console.log(item);
}

// Convert Set to Array
let arrayFromSet = Array.from(set);
let arrayFromSet2 = [...set]; // Using spread operator

// Set operations
let setA = new Set([1, 2, 3]);
let setB = new Set([2, 3, 4]);

// Union
let union = new Set([...setA, ...setB]); // Set(4) {1, 2, 3, 4}

// Intersection
let intersection = new Set([...setA].filter(x => setB.has(x))); // Set(2) {2, 3}

// Difference
let difference = new Set([...setA].filter(x => !setB.has(x))); // Set(1) {1}

Maps

// Creating Maps
let map = new Map();

// Adding key-value pairs
map.set("name", "John");
map.set("age", 30);
map.set(1, "one"); // Key can be any type

// Creating Map from array of key-value pairs
let mapFromArray = new Map([
["name", "Alice"],
["age", 25],
[{ id: 1 }, "object key"]
]);

// Map properties and methods
map.size; // Number of entries
map.get("name"); // "John"
map.has("age"); // true
map.delete("age"); // Remove entry
map.clear(); // Remove all entries

// Iterating Maps
for (let [key, value] of map) {
console.log(`${key}: ${value}`);
}

// Keys, values and entries
Array.from(map.keys()); // Array of keys
Array.from(map.values()); // Array of values
Array.from(map.entries()); // Array of [key, value] pairs

// Map vs Object
// - Map keys can be any type, Object keys are strings or symbols
// - Map has size property, Object doesn't
// - Map maintains insertion order, Object doesn't guarantee order
// - Map is iterable, Object isn't directly iterable
// - Map performs better with frequent additions/removals

// WeakMap (keys must be objects, not iterable, no size property)
let weakMap = new WeakMap();
let objKey = {};
weakMap.set(objKey, "value");
weakMap.get(objKey); // "value"

Iterators

Iterators & Generators

// Custom iterator
class Range {
constructor(start, end) {
this.start = start;
this.end = end;
}

[Symbol.iterator]() {
let current = this.start;
let end = this.end;

return {
next() {
if (current <= end) {
return { value: current++, done: false };
} else {
return { done: true };
}
}
};
}
}

// Using custom iterator
let range = new Range(1, 5);
for (let num of range) {
console.log(num); // 1, 2, 3, 4, 5
}

// Generator function
function* numberGenerator() {
yield 1;
yield 2;
yield 3;
}

let gen = numberGenerator();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }

// Using for...of with generator
for (let value of numberGenerator()) {
console.log(value); // 1, 2, 3
}

// Infinite generator
function* infiniteSequence() {
let i = 0;
while (true) {
yield i++;
}
}

let infinite = infiniteSequence();
console.log(infinite.next()); // { value: 0, done: false }
console.log(infinite.next()); // { value: 1, done: false }

Iterable Objects

// Built-in iterables
let array = [1, 2, 3];
let string = "hello";
let map = new Map([["a", 1], ["b", 2]]);
let set = new Set([1, 2, 3]);

// All are iterable with for...of
for (let item of array) { console.log(item); }
for (let char of string) { console.log(char); }
for (let [key, value] of map) { console.log(key, value); }
for (let item of set) { console.log(item); }

// Using Symbol.iterator explicitly
let arrayIterator = array[Symbol.iterator]();
console.log(arrayIterator.next()); // { value: 1, done: false }

// Making objects iterable
let iterableObject = {
data: ["a", "b", "c"],
[Symbol.iterator]() {
let index = 0;
let data = this.data;

return {
next() {
if (index < data.length) {
return { value: data[index++], done: false };
} else {
return { done: true };
}
}
};
}
};

// Now object is iterable
for (let item of iterableObject) {
console.log(item); // "a", "b", "c"
}

// Using spread operator with iterables
let arrayFromIterable = [...iterableObject]; // ["a", "b", "c"]

// Destructuring with iterables
let [first, second] = iterableObject;
console.log(first, second); // "a", "b"

Regular Expressions

Regex Basics

// Creating regular expressions
let regex1 = /pattern/; // Literal notation
let regex2 = new RegExp("pattern"); // Constructor

// Flags
let regexGlobal = /pattern/g; // Global search
let regexCaseInsensitive = /pattern/i; // Case insensitive
let regexMultiline = /pattern/m; // Multiline
let regexAllFlags = /pattern/gim; // Multiple flags

// Basic patterns
let exactMatch = /hello/; // Matches "hello"
let characterClass = /[aeiou]/; // Matches any vowel
let negatedClass = /[^aeiou]/; // Matches anything except vowels
let range = /[a-z]/; // Matches any lowercase letter
let digit = /\d/; // Matches any digit (0-9)
let wordChar = /\w/; // Matches any word character (a-z, A-Z, 0-9, _)
let whitespace = /\s/; // Matches any whitespace

// Quantifiers
let zeroOrMore = /a*/; // 0 or more 'a's
let oneOrMore = /a+/; // 1 or more 'a's
let zeroOrOne = /a?/; // 0 or 1 'a'
let exactNumber = /a{3}/; // Exactly 3 'a's
let rangeNumber = /a{2,4}/; // 2 to 4 'a's
let atLeastNumber = /a{2,}/; // 2 or more 'a's

// Anchors
let startAnchor = /^Hello/; // Matches "Hello" at start of string
let endAnchor = /world$/; // Matches "world" at end of string
let wordBoundary = /\bword\b/; // Matches "word" as whole word

// Groups
let capturingGroup = /(abc)/; // Capturing group
let nonCapturingGroup = /(?:abc)/; // Non-capturing group
let alternation = /a|b/; // Matches "a" or "b"

Regex Methods

let str = "Hello world! Hello JavaScript!";
let regex = /hello/gi; // Global, case-insensitive

// test() - check if pattern exists
let exists = regex.test(str); // true

// exec() - get match information
let result = regex.exec(str);
// [ "Hello", index: 0, input: "Hello world! Hello JavaScript!", groups: undefined ]

// String methods with regex
// match() - get all matches
let matches = str.match(regex); // [ "Hello", "Hello" ]

// matchAll() - get all matches with details (ES2020)
let allMatches = [...str.matchAll(regex)];
// Array of match objects with details

// search() - get index of first match
let index = str.search(regex); // 0

// replace() - replace matches
let newStr = str.replace(regex, "Hi"); // "Hi world! Hi JavaScript!"

// replace() with function
let replaced = str.replace(regex, match => match.toUpperCase()); // "HELLO world! HELLO JavaScript!"

// split() - split string by pattern
let parts = str.split(/\s+/); // [ "Hello", "world!", "Hello", "JavaScript!" ]

// Practical examples
// Email validation
function isValidEmail(email) {
let emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}

// Extract all numbers from string
function extractNumbers(str) {
return str.match(/\d+/g) || [];
}

// Remove extra whitespace
function normalizeWhitespace(str) {
return str.replace(/\s+/g, " ").trim();
}

// Password strength check (at least 8 chars, with uppercase, lowercase, number)
function isStrongPassword(password) {
let strongRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/;
return strongRegex.test(password);
}