JavaScript

JavaScript

JavaScript is the programming language of the web.
It can update and change both HTML and CSS.
It can calculate, manipulate and validate data.
extension - .js
Single line comments start with //.
Multi-line comments start with /* and end with */.
JavaScript is a case sensitive language.

TypeScript

JavaScript is a dynamically typed language used for web development, whereas TypeScript is a superset of JavaScript that adds static typing, making code more maintainable and reducing runtime errors; however, TypeScript requires compilation (.ts → .js) before execution.
JavaScript (dynamic, quick for small tasks) vs. TypeScript (adds static types, catches errors early, scales for large apps). TS compiles to JS but boosts code safety and teamwork. Use JS for simplicity, TS for complex projects. We can also learn TypeScript in future.

How to use

Internal : JavaScript code is inserted between <script> code </script> tags.
You can place any number of scripts in an HTML document.
Scripts can be placed in the body, or in the head section of an HTML page, or in both.

External : External scripts are practical when the same code is used in many different web pages.
JavaScript files have the file extension .js.
To use an external script, put the name or path of the script file in the src (source) attribute of a <script> tag: <script src="app.js"></script>
You can place an external script reference in head or body as you like. But best practice is At the End of body(The page content loads first, preventing render-blocking delays.).

Variables

variables are used to store data values. JavaScript provides three main ways to declare variables: let, const, and var.

let

let age = 25; or let age; e.t.c
let is block-scoped, meaning it is only accessible within the block (or curly braces) where it is declared. It can be updated but not redeclared within the same block.


const

const pi = 3.14;
Its value cannot be reassigned after initialization.
It must be initialized when declared.
const is also block-scoped like let.


var

var name = "John"; or var name; e.t.c
var is function-scoped, meaning it is accessible within the function where it is declared.
It can be redeclared and updated.

Data Types

Data Types

String - Use double (" ") or single (' ') quotes. Example: let str = "Inderjit 'Singh' "; or let str = 'Inder'; It can also store numbers or be empty: "23", "a", "".
Indexing in JavaScript starts from 0 it can also apply on strings also. e.g str[1] = n
We can also get string length using name.length
String Concatenation - using (+) sign. e.g - "inder" + "jit" = inderjit also like "inder" + 1(number) = inder1

Number - Represents positive, negative, integer, and floating-point numbers. Example: let num = 42; or let num = -3.5;. JavaScript has a maximum limit for numbers.

BigInt - Used for very large numbers beyond the Number type's limit. Example: let bigNum = 9007199254740991n;

Boolean - Represents true or false values. Example: let isCodingFun = true;

Undefined - A variable that has been declared but not assigned a value. Example: let x; // undefined

Null - Represents an empty or unknown value. Example: let data = null;

Symbol - Used to create unique identifiers. Example: let sym = Symbol('id');

Object - A complex data type used to store key-value pairs. Example: let person = { name: "Inder", age: 20 };

JavaScript automatically detects the data type when a variable is assigned a value.
We can change the type of variables in JavaScript. Example: let value = "Hello"; // String, then value = 25; // Now Number


Nan

NaN stands for "Not-a-Number." It is a special value that represents an undefined or unrepresentable number, especially when a mathematical operation cannot return a valid number.
e.g = let result = 0 / 0; - result will be NaN,
let number = Number("hello"); // number will be NaN
To check if a value is NaN, you cannot directly use the equality operator (===) because NaN is not equal to itself. Instead, you should use the Number.isNaN() method:
let value = NaN;
console.log(Number.isNaN(value)); // true

Operators

Javascript operators are used to perform different types of mathematical and logical computations.

Types of JavaScript Operators

Operator Type Description Example
Arithmetic Operators Used to perform mathematical calculations. +, -, *, /, %, ++, --, **
Assignment Operators Used to assign values to variables. =, +=, -=, *=, /=, %=, **=
Comparison Operators Used to compare two values and return a boolean value. ==, ===, !=, !==, >, <, >=, <=
Logical Operators Used to perform logical operations between two or more expressions. && (AND), || (OR), ! (NOT)
Unary Operators Operates on a single operand. +, -, ++, --, !
Bitwise Operators Used to perform bit-level operations. &, |, ^, ~, <<, >>, >>>
Conditional (Ternary) Operator Used to perform conditional evaluation. condition ? expr1 : expr2
Typeof Operator Used to check the type of a variable or expression. typeof x
Instanceof Operator Used to check if an object is an instance of a specific class. obj instanceof Class
Comma Operator Used to evaluate multiple expressions and return the last result. expr1, expr2

comparison operators

Comparing Strings

JavaScript compares strings character by character based on Unicode values.
e.g - onsole.log("apple" > "banana"); // false (because "a" < "b" in Unicode)
a(61) < b(62) < c(63) e.t.c OR A(41) < B(42) < C(43) e.t.c OR A < a e.t.c.
also console.log('*' < '&') // false e.t.c.


Operator Precendence

For some operators : () > ** > *, /, % > +, -
if two operators with same precedence then calculate from left to right
there are more operators with different precedence levels.

Identifiers

All JavaScript variables must be identified with unique names. These unique names are called identifiers.

rules:-

Names can contain letters, digits, underscores, and dollar signs.
Names must begin with a letter.
Names can also begin with $ and _ (but not start with numbers).
Names are case sensitive (y and Y are different variables).
Reserved words (like JavScript keywords) cannot be used as names.

camelCase

We use camelCase for identifier names (variables and functions) in JavaScript.
Camel Case: Use camel case for variable and function names. The first letter is lowercase, and each subsequent word starts with an uppercase letter.
e.g - firstName, totalPrice, lastWord e.t.c.
It's not mandatory, but following these practices can help improve coding standards.

JS Output

console.log()

console.log() is used to print output to the browser's console. It is mainly used for debugging.
e.g: console.log("Hello World");, console.log(num);, console.log(1+2);, console.log("Hello", num, (1+2)); e.t.c.

Template Strings

Template Strings (also known as Template Literals) are a feature that allow for easier and more readable string manipulation in JavaScript. In this we write inside backticks(``)

1. String Interpolation (Embedding Variables & Expressions)

Template literals allow you to embed variables and expressions directly within a string using ${}.
console.log(`Hello, my name is ${name} and I am ${age} years old.`);
Output: Hello, my name is Alice and I am 25 years old.


2. Multi-line Strings (Without \n or Concatenation)

Template literals preserve newlines and whitespace automatically.
e.g: const message = `This is a multi-line,
string in JavaScript.`;
console.log(message); - No need for + operators or \n!


3. Expression Evaluation (Math, Functions, etc.)

You can perform calculations and function calls inside ${}.
e.g : console.log(`The sum of ${x} and ${y} is ${x + y}.`);

Conditional Statement

If, else, else if statements

if,else,else if

Switch statements

if,else,else if

Alerts & Prompts

alert()

The alert() function displays a simple message in a dialog box with an "OK" button.
e.g - alert("This is an alert!");

console.error()

Used to log error messages. It highlights the message in red and may include a stack trace.
console.error("This is an error message!");

console.warn()

Used to log warning messages. It displays messages in yellow.
console.warn("This is a warning message!");

prompt()

The prompt() function is used to get user input via a popup dialog box with a text field.
let userInput = prompt("Enter your name:");
Returns null if the user clicks "Cancel".
We can manupulate all these methods in many ways or use their combination we can also learn that.

String Methods

Javascript strings are primitive and immutable: All string methods produce a new string without altering the original string.
syntax - stringName.method()

Arguments - is some value that we pass to the method. but not every method accepts arguments.
syntax - stringName.method(arguments)

String length

The length property returns the length of a string.(it is a property not method but i included here)
syntax - stringName.length;

trim()

The trim() method removes whitespace from both sides of a string.
let text1 = "   Hello   "; let text2 = text1.trim(); // text2 = "Hello"

toUpperCase() and toLowerCase()

A string is converted to upper case with toUpperCase().
A string is converted to lower case with toLowerCase().
e.g = str = "HELLO world"
str.toUpperCase() - HELLO WORLD, str.toLowerCase() - hello world

inderOf(arg)

The indexOf() method returns the index (position) of the first occurrence of a string in a string, or it returns -1 if the string is not found.
let text = "Please locate where 'locate' occurs!";
let index = text.indexOf("locate"); // output: 7

slice()

slice() extracts a part of a string and returns the extracted part in a new string.
The method takes 2 parameters: start position, and end position (end not included).
e.g - let text = "Apple, Banana, Kiwi";
one argument - text.slice(7, 13); - "Banana"
only one argument - text.slice(7) - "Banana, Kiwi" (in this last = length of string);
negative argument - text.slice(-5) - "Kiwi" (because length(here 19) - 5 = 14) == text.slice(14);

replace()

The replace() method replaces a specified value with another value in a string.
e.g - let str = "i love coding"
str.replace("love","do") - output: "i do coding";
It only replace first occurance by default.
e.g - str.replace("o","x") - output: "i lxve coding" (only changed first o).

repeat()

The repeat() method returns a string with a number of copies of a string.
e.g - let str = "Hello"
str.repeat(5) - output: "HelloHelloHelloHelloHello"

All methods

charAt(), charCodeAt(), concat(), includes(), indexOf(), lastIndexOf(), localeCompare(), match(), matchAll(), normalize(), padEnd(), padStart(), repeat(), replace(), replaceAll(), search(), slice(), split(), startWith(), endsWith(), substring(), substr(), toLowerCase(), toUpperCase(), toLocaleLowerCase(), toLocaleUpperCase(), trim(), trimStart(), trimEnd(), valueOf(), split(), anchor(), big(), blink(), bold(), fixed(), fontcolor(), fontsize(), italics(), link(), small(), strike(), sub(), sup().
we can learn more methods.

Method Chaining

Method chaining in JavaScript refers to the technique of calling multiple methods on the same object or value in a single line of code.
let str = "   Hello World!   "
let result = str.trim().toUpperCase().replace("WORLD", "EVERYONE");
console.log(result); // "HELLO EVERYONE!"
Method chaining works if the methods return the object or value that the next method expects.

Arrays

Arrays

An array is a special variable that can hold multiple values in a single reference.
Arrays in javascript are zero-indexed.
Arrays are mutable in javascript.
Arrays in JavaScript are dynamic (can change size) and can store different data types.
e.g = let arr = ["Apple", 23, 89.5]; - (array with different datatypes).

Creating an Array

Using Array Literal (Preferred Method):-
let fruits = ["Apple", "Banana", "Cherry"];

Using new Array() Constructor:-
let numbers = new Array(1, 2, 3, 4, 5);

Empty Array and Adding Elements:-
let arr = [];
arr[0] = "Hello";
arr[1] = "World";

Accessing Array Elements

1. console.log(fruits[1]); // Output: Banana

2. console.log(fruits[2][0]); // Output: C - (we can access index of elements of arrays like this).

3. array.length - Returns the number of elements in the array.(it is a property)
e.g fruits.length - 3
also length of elements - fruits[0].length - 5
also we can directly see length [1,2,3,4].length - 4

Modifying Arrays

As arrays are mutable.
let array = ["Apple", "Mango", "Cherry"];
array[0] = "Banana";
console.log(array) // Output: ["Banana", "Mango", "Cherry"] (array is changed).

we can add element in any index:-
array[10] = "Grapes";
console.log(array) // Output: ["Banana", "Mango", "Cherry", empty x 7, "Grapes"] (now the array.length = 11)
if we add element at index like greater then previous length then it is added to that index but there may empty spaces.
console.log(array[5]) //Output: undefined (as no element is present even array length is 11).

Array Methods

push()

The push() method adds a new element to an array (at the end).
let fruits = ["Banana", "Orange"];
fruits.push("Kiwi");
console.log(fruits); // Output: ["Banana", "Orange", "Kiwi"]

pop()

The pop() method removes the last element from an array and return it.
fruits.pop()
console.log(fruits); // Output: ["Banana", "Orange"]

unshift()

The unshift() method adds a new element to an array (at the beginning), and "unshifts" older elements.
fruits.unshift("Apple")
console.log(fruits); // Output: ["Apple", "Banana", "Orange"]

shift()

The shift() method removes the first array element and return it, "shifts" all other elements to a lower index.
fruits.unshift()
console.log(fruits); // Output: ["Banana", "Orange"]

indexOf()

the .indexOf() method is used to find the index of a specific element in an array.
syntax - array.indexOf(element, fromIndex).
element - The value to search for.
fromIndex (optional) - The index to start searching from (default is 0).
e.g - fruits.indexOf("Orange"). //output: 1
it returns - The first index where the element if found OR -1 if the element is not found.

includes()

the .includes() method is used to check if an array contains a specific element.
syntax - array.includes(element, fromIndex)
element - The value to search for.
fromIndex (optional) - The index to start searching from (default is 0).

e.g - fruits.includes("Orange"). //output: true
it returns - true or false.

concat()

the .concat() method is used to merge two or more arrays without modifying the original arrays.
syntax - newArray = array1.concat(array2, array3, ...);
we write which array first their element become first

e.g - let fruits2 = ["Apple", "Mango"];
let result = fruits.concat(fruits2);
console.log(result); // Output: ["Banana", "Orange", "Apple", "Mango"]

reverse()

the .reverse() method is used to reverse the order of elements in an array.
syntax - array.reverse();
It modifies the original array and returns the same array.

e.g - result.reverse(); // Output: ["Mango", "Apple", "Orange", "Banana"]

slice()

.slice() method is used to extract a portion of an array without modifying the original array.
syntax - array.slice(startIndex, endIndex);
startIndex (optional) - The index where extraction begins (inclusive).
endIndex (optional) - The index where extraction stops (exclusive).
If no parameters are given, it returns a copy of the entire array.

let num = [1,2,3,4]; e.g - result.slice(); // Output: [1, 2, 3, 4]
e.g - result.slice(2); // Output: [3, 4]
e.g - result.slice(1,3); // Output: [2, 3]
e.g - result.slice(-4,-2); // Output: [1, 2]

splice()

The .splice() method is used to add, remove, or replace elements in an array by modifying the original array.
syntax - array.splice(startIndex, deleteCount, item1, item2, ...);
startIndex - The position where changes begin.
deleteCount (optional) - The number of elements to remove.
item1, item2, ... (optional) - Elements to insert at startIndex.

e.g :-
let arr = [10, 20, 30, 40, 50]; let removed = arr.splice(2, 2); console.log(arr); // Output: [10, 20, 50] (modified)
console.log(removed); // Output: [30, 40] (removed elements)
arr.splice(2, 0, 3, 4);
console.log(arr); // Output: [10, 20, 3, 4, 50] (deleted 0 added 3,4).
arr.splice(2);
console.log(arr); // Output: [10, 20] (Since deleteCount is not provided, all elements from index 2 onward are removed.)

sort()

The sort() method sorts an array alphabetically and modifies the original array.
syntax - array.sort OR array.sort(compareFunction);
compareFunction (optional) - A function that defines the sorting order.
By default, it sorts elements as strings in ascending order.

e.g :-
let fruits = ["Banana", "Apple", "Mango", "Orange"];
fruits.sort();
console.log(fruits); // Output: ["Apple", "Banana", "Mango", "Orange"]
let numbers = [100, 3, 20, 40];
numbers.sort();
console.log(numbers); // Output: [100, 20, 3, 40] ( Issue: Numbers are converted to strings and sorted based on the first digit (not numerical order)).

forEach()

The forEach() method in JavaScript is used to iterate over each element of an array. It executes a provided callback function once for each array element.

Syntax:- array.forEach(function(element, index, array) {   // Code to execute }); element: The current element being processed. index: (Optional) The index of the current element. array: (Optional) The array on which forEach is called.
Examples:- let arr = [1, 2, 3, 4, 5]; // 1.Using Arrow Function arr.forEach((el) => {   console.log(el); //print all elements }); // 2.Using Regular Function arr.forEach(function (el) {   console.log(el); //print all elements }); // 3.Using a Named Function let print = function (el) {   console.log(el); //print all elements }; arr.forEach(print); //Using index arr.forEach((num, index) => { console.log(`Element at index ${index} is ${num}`); }); // Output: Element at index 0 is 1....print all like this there are other ways possible also...

map()

The map method creates a new array by applying a callback function to each element of the original array. It transforms the elements and returns the result without modifying the original array.

Syntax:- array.map((element, index, array) => {   // Return transformed element }); OR array.map(functionName); //many syntax possible element: The current element being processed. index: (Optional) The index of the current element. array: (Optional) The array on which forEach is called.
Examples:- //1.using arrow function const numbers = [1, 2, 3, 4]; const doubled = numbers.map(num => num * 2); console.log(doubled); // Output: [2, 4, 6, 8] //2.using named function const multiplyBy2 = function(num) {   return num * 2; }; const arr2 = [7, 8, 9]; const doubled = arr5.map(multiplyBy2); console.log(doubled); // Output: [14, 16, 18] there are other ways may possible also...

filter()

The filter method creates a new array containing only the elements that pass a test (return true) in the callback function. It’s used to select a subset of elements without altering the original array.

Syntax:- array.filter((element, index, array) => {   // Return transformed element }); OR array.filter(functionName); //many syntax possible element: The current element being processed. index: (Optional) The index of the current element. array: (Optional) The array on which forEach is called.
Examples:- //1.using arrow function const arr = [10, 15, 20, 25]; const greaterThan15 = arr2.filter(num => num > 15); console.log(greaterThan15); // Output: [20, 25] //2.using named function const isOdd = function(num) {   return num % 2 !== 0; }; const arr2 = [7, 8, 9]; const oddNumbers = arr5.filter(isOdd); console.log(oddNumbers); // Output: [7, 9] there are other ways may possible also...

every()

The every method checks if all elements in an array satisfy a given condition. It returns true if every element passes. false if at least one element fails the test. It stops processing as soon as it encounters the first element that doesn't meet the condition(this is called short-circuiting).

Syntax:- array.filter(function definition or Name); //there are other syntax also
Example:- //using arrow function const numbers = [1, 2, 3, 4, 5]; const allEven = numbers.every(num => num%2==0); console.log(allEven); // Output: false, because not every element is even there are other ways may possible also...

some()

The some method checks if at least one element in an array satisfies a given condition. It returns: true if at least one element passes. false if no elements pass. It stops processing as soon as it finds the first element that meets the condition (short-circuiting).

Syntax:- array.some(function definition or Name); //there are other syntax also
Example:- //using arrow function const numbers = [1, 2, 3, 4, 5]; const hasEven = numbers.some(num => num%2 == 0); console.log(hasEven); // Output: true, because atleast there one even element or more there are other ways may possible also...

reduce()

The reduce() method is used to iterate through an array and accumulate a single value based on a callback function. It processes each element of the array (from left to right) and returns a single value result.

Syntax:- array.reduce((accumulator, currentValue, index, array) => {   // logic here }, initialValue); // index, array, initialValue are optional //If no initial value is given, reduce starts from the first element. However, for cases like sum, it's better to set it to 0 to avoid errors. array.reduce(function definition(accumulator, element) or Name); //there are other syntax also
Example:- const numbers = [1, 2, 3, 4]; const sum = numbers.reduce((acc, num) => acc + num); console.log(sum); // Output: 10 there are other ways possible also...

All array methods names

push(), pop(), unshift(), shift(), splice(), slice(), concat(), indexOf(), lastIndexOf(), includes(), find(), findIndex(), forEach(), map(), filter(), reduce(), some(), every(), sort(), reverse(), join(), split(), flat(), flatMap(), fill(), copyWithin(), toString(), toLocaleString(), Array.isArray().
We can also learn about them.

Array Reference

Array Reference

In JavaScript, arrays are reference types, meaning they are stored in memory as objects, and variables hold references (memory addresses) to these arrays rather than their actual values.
Assigning Arrays by Reference - When you assign an array to another variable, both variables point to the same array in memory.
e.g:-
arr refrences
Copying Arrays Without Reference - To create new independent copy of an array (instead of referencing the same memory), there are many methods for now Using .slice() or assign manually.

const Array

When you declare an array with const, the reference to the array remains fixed, meaning you cannot reassign it to a new array. However, the elements inside the array can still be modified.
declaretion - const arr = [1, 2, 3];
Modifying Elements (Allowed) - like push, pop, adding, removing elements.
Reassigning a Constant Array (Not Allowed) - like arr = [1,2]; on same array.

Multi-dimensional Arrays

Multi-dimensional Arrays

A nested array is an array inside another array. It is also called a multi-dimensional array.

let nestedArr = [[1, 2], [3, 4], [5, 6]]; console.log(nestedArr); // Output: [[1, 2], [3, 4], [5, 6]] console.log(nestedArr[0]); // Output: [1, 2] (First inner array) console.log(nestedArr[0][1]); // Output: 2 (Second element of first inner array)
We can perform all operations, methods e.t.c of arrays on multi-dimensional arrays as well.

Loops

For loop

for loop

While loop

while loop

break keyword

The break statement in JavaScript is used to exit a loop immediately when a specific condition is met.

for (let i = 0; i < 5; i++) {   if (i === 3) {     break; // Exits the loop when i is 3   }   console.log("Iteration:", i); }

for of loop

The for...of loop in JavaScript is used to iterate over iterable objects like arrays, strings, maps, and sets.
for of loop

Examples:- let numbers = [10, 20, 30, 40]; for (let num of numbers) {   console.log(num); } let word = "Hello"; for (let char of word) {   console.log(char); }
We can also Use nested for..of loops.

Object Literals

Object Literals

An object literal is a way to define an object using a set of key-value pairs enclosed in curly braces {}.
Key-Value Pairs - Each property has a key (property name) and a value.
A single key can hold multiple values using arrays, objects, or other data structures.
objects are unordered collections do not maintain a fixed order,Objects do not have indexing like arrays.

Example:- const person = {   firstName: "John",   lastName: "Doe",   scores: { math: 90, science: 85, english: 88 } // Nested object   fullName: function() {     return this.firstName + " " + this.lastName;   } }; This creates an object with properties like firstName, lastName, scores and a method fullName. Here, fullName is a method. calling person.fullName() returns 'John Doe'

A const object behaves like a const array - you can modify its contents but cannot reassign it.

Accessing Object Properties

You can access object properties using object.key or object["key"].

const person = { firstName: "John", lastName: "Doe" }; // Using dot notation console.log(person.firstName); // Output: "John" // Using bracket notation console.log(person["lastName"]); // Output: "Doe" //for nested objects console.log(person.scores.math); // Output: 90 OR like console.log(person["scores"]["math"]); // Output: 90

JavaScript Automatically Converts Object Keys to Strings :-

const obj = {   "null": "a",   2:"b" }; console.log(obj.null); // Output: "a" console.log(obj["2"]); // Output: "b"

Add/Update values

const obj = {   a: 1,   b: 2 }; obj.c = 3; // Adding new property using dot obj["d"] = 4; // Adding another property using square brackets obj.a = [10,20]; // Updating existing property obj["b"] = "two"; // Updating another property console.log(obj); // Output: { a: [10,20], b: "two", c: 3, d: 4 }

Delete values

We can use the delete operator to remove a property from an object.

const obj = {   a: 1,   b: 2,   c: 3 }; delete obj.c; // Deleting property 'c' delete obj["b"]; // Deleting property 'b' console.log(obj); // Output: { a: 1 }

Nested Objects

const obj = {   person1: { name: "John", age: 25 },   person2: { name: "Alice", age: 30 } }; console.log(obj.person1.name);

Array of Objects

const arr = [   { name: "John", age: 25 },   { name: "Alice", age: 30 } ]; console.log(arr[0].name);

Object Functions(Methods)

Object methods are functions that are defined inside an object and can operate on the object's properties. They provide behavior to the objects.

const calculator = {   // Key-value pair method   sub: function(a, b) {     return a - b;   },   // Shorthand method without key   add(a, b) {     return a + b;   } }; console.log(calculator.add(5, 3)); // Output: 8 console.log(calculator.sub(10, 4)); // Output: 6

Math Object

The Math object is a built-in JavaScript object that provides mathematical functions and constants.

Math Properties (Constants)

The syntax for any Math property is : Math.property.

Property Description Value
Math.PI Returns the value of Pi (π) 3.141592653589793
Math.E Returns Euler’s number (e) 2.718281828459045
Math.SQRT2 Returns the square root of 2 1.4142135623730951
Math.SQRT1_2 Returns the square root of 1/2 (1/√2) 0.7071067811865476
Math.LN2 Returns the natural logarithm of 2 0.6931471805599453
Math.LN10 Returns the natural logarithm of 10 2.302585092994046
Math.LOG2E Returns the logarithm base 2 of e 1.4426950408889634
Math.LOG10E Returns the logarithm base 10 of e 0.4342944819032518

Math Methods

The syntax for Math any methods is : Math.method(number).

Method Description Example
Math.round(x) Rounds x to the nearest integer Math.round(4.6) → 5
Math.floor(x) Rounds x down to the nearest integer Math.floor(4.9) → 4
Math.ceil(x) Rounds x up to the nearest integer Math.ceil(4.1) → 5
Math.trunc(x) Removes the decimal part of x Math.trunc(4.9) → 4
Math.abs(x) Returns the absolute value of x Math.abs(-5) → 5
Math.sqrt(x) Returns the square root of x Math.sqrt(16) → 4
Math.pow(x, y) Returns x raised to the power of y Math.pow(2, 3) → 8
Math.max(a, b, ...) Returns the largest number Math.max(10, 20, 5) → 20
Math.min(a, b, ...) Returns the smallest number Math.min(10, 20, 5) → 5
Math.random() Returns a random number between 0 and 1 Math.random() → 0.54321
Math.log(x) Returns the natural logarithm of x Math.log(10) → 2.302
Math.sin(x) Returns the sine of x (radians) Math.sin(Math.PI / 2) → 1
Math.cos(x) Returns the cosine of x (radians) Math.cos(0) → 1
Math.tan(x) Returns the tangent of x (radians) Math.tan(Math.PI / 4) → 1

random integer - to print any random numbers between any range we can manupulate Math.random
e.g - to print between x to y - Math.floor(Math.random() * (y - x + 1)) + x; e.t.c

Functions

Functions

There are several ways to define a function in JavaScript.

Function Declaration:- function name(parameter1, parameter2....) {   // code to be executed }

Assigned to a variable(Function Expression) :-

Function Expression:- const add = function(a,b) {   return a+b; } console.log(add(5, 3)); we can also change value of add later.

return - anything after return statement will not execute.

Default Parameters

Default parameters allow you to set default values for function arguments if no value or undefined is passed.

Function Declaration:- function functionName(parameter = defaultValue) {//function body}
Examples:- //1.with normal functions function calculateArea(length, width = 3) {   return length * width; } console.log(calculateArea(7)); // Output: 21 (7 * 3) //2.with arrow functions const multiply = (a = 2, b = 3) => a * b; console.log(multiply(4)); // Output: 12 (4 * 3) const multiply = (a = 3, b) => a * b; console.log(multiply(4)); // Output: NaN, because 4 is assigned to a and b remains undefined So, Use default parameters at last..

The default value is used if the argument is undefined but not if it is null or a falsy value like 0.

Higher-Order Functions

Higher-order functions in JavaScript are functions that can either take other functions as arguments, return a function as a result, or both.

1. Passing a Function as an Argument let greet = function() {   console.log("Hello"); } function higherOrder(func,n) {   for(i = 0;i < n; i++){     func();   } } higherOrder(greet,5); //Output: Hello (5 times)
2. Returning a Function function oddEvenTest(request) {   if (request === "odd") {     return function(n) {       console.log(!(n % 2 === 0))     };   } else if(request === "even") {     return function(n) { console.log(n % 2 === 0); };   } } // Using the function let checkOdd = oddEvenTest("odd"); checkOdd(5); // Output: true let checkEven = oddEvenTest("even"); checkEven(7); // Output: false

Arrow Functions

Arrow functions(=>) are a shorter syntax for writing function expressions. They were introduced in ES6 and are often used for shorter, simpler functions.

Syntax:- const name = (param1, param2....) => {   // Code block };
if we have single parameter we can also skip () paranthesis:- const func = param => {   // Code block };
Implicit Return: const square = x => x * x; // Implicit return Implicit Return: If there's only one expression, you can skip the {} and return. there may also possible more syntax.

No this Binding: Arrow functions do not have their own this. They inherit this from their lexical scope. If you need this to refer to the object, use a regular function instead.
Cannot be used as Constructors: They can't be used with the new keyword.

Scope

Scope determines the accessibility of variables, objects, and functions in different parts of your code. It controls where variables can be accessed or modified.

1. Global Scope

Variables declared outside of any function or block. Accessible from anywhere in the code.

2. Local Scope

Variables declared inside a function. Accessible only within that function.

function localScope() {   let localVar = "I am local";   console.log(localVar); // Accessible } localScope(); console.log(localVar); // Error: localVar is not defined

3. Block Scope (ES6)

Variables declared with let or const inside curly braces {}. Accessible only within that block.

{   let blockLet = "I am block scoped";   console.log(localVar); // Accessible   var functionVar = "I am function scoped"; } console.log(blockLet); // Error: localVar is not defined console.log(functionVar); // Accessible because defined with var keywoard but we don't prefer that

4. Function Scope

Variables declared with var are function-scoped. Accessible only within the function, but not restricted by blocks.

function funcScope() {   var funcVar = "I am function-scoped";   if (true) {     var insideIf = "Still in function scope";   }   console.log(funcVar); // Accessible   console.log(insideIf); // Accessible } funcScope(); console.log(funcVar); // Error: funcVar is not defined

5. Lexical Scope

Inner functions have access to variables of their parent functions. This concept forms the basis of closures.

function outer() {   let outerVar = "I am from outer";   function inner() {     console.log(outerVar); // Accessible due to lexical scope   }   inner(); //Works fine } outer(); //Works fine inner(); //Error: inner is not defined (Function scope)
Scope Type Keyword Accessibility
Global var, let, const Anywhere in the code
Local var, let, const Within the function only
Block let, const Within the block {}
Function var Within the function, not block-based
Lexical - Access to parent function variables

Scope Chain

If a variable is not found in the current scope, JavaScript looks up in the outer scope until the global scope.

let x = 10; function first() {   let x = 20;   let y = 30;   console.log(x, y); // 20, 30 (Local scope has priority over global scope) } first();

This Keyword

this keyword refers to the object that is executing the current piece of code - whether it's a function, method, constructor or in global scope(window).The value of this can vary depending on where and how it is used.

1. Global Context

In the global scope (outside of any function), this refers to the global object (window in browsers, global in Node.js).

console.log(this); // Logs the window object in browsers

2. Inside a Method (Object Context)

When used inside an object method, this refers to the object calling the method.

const person = {   name: "Alex",   greet() {     console.log(this.name); // "Alex"     console.log(name); // Error: name is not defined   } }; person.greet(); When we use console.log(name) without this, JavaScript searches for name in the local and global scope. Since it's not found, it throws a ReferenceError.

3. Inside a Normal Function

In normal functions, the value of this depends on the calling object — the object that invokes the function. It is determined at runtime and is dynamic.

const person = {   name: "Alex",   showName: function() {     console.log(this.name); // 'this' refers to the person object   },   getInfo: function () {     setTimeout(function () {       console.log(this); // 'this' refers global object, not person object     }, 2000);   } }; // A separate normal function to show how 'this' works globally function showGlobalThis() {   console.log(this); //this will refer to the global object } person.showName(); // Output: "Alex" showGlobalThis(); // Output: Window object (in browsers)

4. Inside a Arrow Functions

In arrow functions, this has lexical scoping. It inherits this from its parent scope (the scope where it was defined), and it cannot be changed by how or where it is called.

const student = {   name: "Aman",   marks: 95,   prop: this, // Global scope   getMarks: () => { //arrow function     console.log(this); // 'this' refers global object, not student object     return this.marks; // undefined   },   getInfo1: function () { //arrow function     setTimeout(() => {       console.log(this); // 'this' refers to student object (lexical scope)     }, 2000);   }, };

This has many other uses here short summary:-

Context What "this" Refers To Example Output
Global Scope Global object (window in browsers) console.log(this); window
Inside a Function (Non-Strict Mode) Global object (window in browsers) function test() { console.log(this); } test(); window
Inside a Function (Strict Mode) undefined 'use strict'; function test() { console.log(this); } test(); undefined
Inside an Object Method The object calling the method const obj = { name: "Alex", show() { console.log(this.name); } }; obj.show(); "Alex"
Inside a Constructor The new instance created function Car(model) { this.model = model; } const myCar = new Car("Tesla"); console.log(myCar.model); "Tesla"
Arrow Function Lexically inherits "this" from parent scope const obj = { name: "Sam", show: () => console.log(this); }; obj.show(); Global object (window)
DOM Event Handler The HTML element that received the event <button onclick="console.log(this)">Click</button> The button element
Class Method The instance of the class class Person { constructor(name) { this.name = name; } greet() { console.log(this.name); } } const p = new Person("Alex"); p.greet(); "Alex"
setTimeout (Regular Function) Global object (non-strict mode) setTimeout(function() { console.log(this); }, 1000); window
setTimeout (Arrow Function) Inherits "this" from its surrounding scope const obj = { name: "Alex", show() { setTimeout(() => console.log(this.name), 1000); } }; obj.show(); "Alex"

Try and Catch

try...catch is a JavaScript mechanism for handling errors gracefully. It helps you catch and manage exceptions that may occur during runtime, preventing the entire application from crashing.

try block

The try block contains code that might throw an error. JavaScript attempts to execute this code. If no error occurs, it runs normally, and the catch block is skipped. If an error does occur, execution stops in the try block, and control jumps to the catch block.

catch block

The catch statement allows you to define a block of code to be executed, if an error occurs in the try block.It receives an error object as an argument(optional).If we used try then catch must also be used with it otherwise error come also.

finally Block (Optional)

You can add a finally block after try and catch. This block runs no matter what—whether an error occurred or not. It's commonly used for cleanup tasks, such as closing resources.

example

Common Use Cases:
Handling network requests or API failures.
Preventing application crashes due to undefined variables or incorrect data types.
Providing meaningful error messages to users.

syntax:- try {   // Code that may throw an error } catch (error) {   // Code to handle the error. error argument optional here } finally {   // Optional block that runs regardless of error }
example:- try {   console.log(undeclaredVariable); // This will throw a ReferenceError } catch (error) {   console.log("An error occurred!"); // Simple error message   console.log(error); //print the entire error object   console.log("Error Name:", error.name); // ReferenceError   console.log("Error Message:", error.message); // undeclaredVariable is not defined } finally{   console.log("Execution completed"); } error.name: Type of the error (like ReferenceError, TypeError, etc.) error.message: A description of the error. error.stack: Information about where the error occurred. at place of error argument we can use any name like err e.t.c

Windows Object

The window object is the global object in the browser environment. It represents the browser window or tab where JavaScript is running. It is automatically created by the browser.
e.g - If a document contain frames (<iframe> tags), the browser creates one window object for the HTML document, and one additional window object for each frame.

Features of Window Object

Global Scope: All global variables and functions are properties and methods of the window object.

var x = 10; console.log(window.x); // Output: 10

Implicit Reference: You can omit window while accessing its properties and methods.

window.alert("Hello!"); // Same as alert("Hello!");

Global variables declared with var become properties of the window object. However, variables declared with let or const do not.

properties and methods

Some Window Object properties and methods there are many more also

Property/Method Description Example
window.alert() Displays an alert box window.alert("Hello!")
window.prompt() Displays a dialog box for user input let name = window.prompt("Name:")
window.confirm() Shows a confirmation dialog box window.confirm("Are you sure?")
window.location Information about the current URL console.log(window.location.href)
window.history Accesses browser history window.history.back()
window.navigator Information about the browser console.log(window.navigator.userAgent)
window.setTimeout() Executes code after a delay window.setTimeout(() => alert("Hi"), 2000)
window.setInterval() Repeats code at set intervals window.setInterval(() => console.log("Tick"), 1000)
window.open() Opens a new browser window or tab window.open("https://example.com")
window.close() Closes the current window window.close()
window.innerWidth Width of the window's viewport console.log(window.innerWidth)
window.innerHeight Height of the window's viewport console.log(window.innerHeight)

setTimeout and setInterval

setTimeout

setTimeout() is a built-in JavaScript function that executes a piece of code or a function(callback) after a specified delay (in milliseconds).

Syntax:- setTimeout(function, delay, arg1, arg2, ...); function: The function to be executed after the delay. delay: Time in milliseconds (1000 ms = 1 second). arg1, arg2, ... (optional): Additional arguments to pass to the function.

Example 1: Using a Named Function

function greet() {   console.log("Hello, World!"); } setTimeout(greet, 2000); // Runs after 2 seconds

Example 2: Using an Anonymous Function(without name)

setTimeout(() => {   console.log("This runs after 3 seconds!"); }, 3000);

Example 3: Passing Arguments

function displayMessage(name, age) {   console.log(`Hello ${name}, you are ${age} years old!`); } setTimeout(displayMessage, 1500, "Alex", 21); // Runs after 1.5 seconds

Example 4: Clearing a Timeout

let timeoutId = setTimeout(() => {   console.log("This won't run!"); }, 3000); clearTimeout(timeoutId); // Cancels the timeout // Runs after 1.5 seconds

setInterval

setInterval() is a built-in JavaScript function that repeatedly executes a function or code snippet at a specified time interval (in milliseconds) until it's stopped.

Syntax:- setInterval(function, interval, arg1, arg2, ...); arguments are optional same syntax as setTimeout

Example 1: Using a Named Function (all Syntax same as setTimeout)

function showTime() {   console.log(new Date().toLocaleTimeString()); } setInterval(showTime, 1000); // Displays time every 1 second

Example 2: Using an Anonymous Function (without name)

setInterval(() => {   console.log("Repeating message every 2 seconds!"); }, 2000);

Example 3: Passing Arguments

function greet(name) {   console.log(`Hello, ${name}!`); } setInterval(greet, 3000, "Alex"); // Runs every 3 seconds with argument "Alex"

Example 4: Clearing an Interval. If we not clear interval it will run infinitely

let count = 0; const intervalId = setInterval(() => {   count++;   console.log(`Count: ${count}`);   if (count === 5) {     clearInterval(intervalId);     console.log("Interval cleared!"); } }, 1000); //using setTimeout let id = setInterval(() => {   console.log("Hello"); }, 2000); //print Hello 5 times after that setTimeout runs clearInterval setTimeout(() => {   clearInterval(id); }, 10000);

Spread/Rest

spread(...) operator

The spread operator (...) allows you to expand or unpack elements from arrays, objects, or iterables. It helps create copies of arrays/objects, merge them, and pass multiple elements as function arguments.

1.Copying Arrays const original = [1, 2, 3]; const copy = [...original]; console.log(copy); // [1, 2, 3]
2.Merging Arrays const arr1 = [1, 2]; const arr2 = [3, 4]; const merged = [...arr1, ...arr2]; console.log(merged); // [1, 2, 3, 4]
3.Passing Arguments to Functions When a function expects multiple arguments, you can use the spread operator to pass elements of an array as individual arguments. const numbers = [5, 10, 2]; const max = Math.max(...numbers); console.log(max); // 10
4.Expanding Strings or Other Iterables const str = "hello"; const chars = [...str]; console.log(...str); // h e l l o console.log(chars); // ['h', 'e', 'l', 'l', 'o']
5.With Object Literals // 1. Copying and Extending an Object const data = { email: "ironman@gmail.com", password: "abcd" }; const dataCopy = { ...data, id: 123, }; console.log(dataCopy); // Output: { email: "ironman@gmail.com", password: "abcd", id: 123} // 2. Spreading an Array(also srting) into an Object let arr = [1, 2, 3, 4, 5]; let obj1 = { ...arr }; //using {} console.log(obj1); // Output: { 0: 1, 1: 2, 2: 3, 3: 4, 4: 5 } many other uses of spread also...

The spread operator only creates a shallow copy. Changes to nested objects affect the original. If an array contains objects, those objects are still referenced, not cloned.

rest(...) parameter

The rest parameter (...) is used in function definitions to gather multiple arguments into an array. It helps handle a variable number of arguments easily.

Syntax:- function funcName(...restParameter) {   // Code using restParameter as an array }
1.Rest in Functions function sum(...numbers) {   return numbers.reduce((acc, curr) => acc + curr); } console.log(sum(1, 2)); // Output: 3 console.log(sum(4, 5, 6, 7)); // Output: 22
2.With other parameters function multiply(multi, ...numbers) {   return numbers.map(num => num * multi); //multi = 2 } console.log(multiply(2, 1, 2, 3)); // Output: [2, 4, 6] //always use other parameters in starting many other ways to use...

Spread VS Rest: Rest collects multiple elements into an array. Spread expands elements from an array or object.

Destructuring

Destructuring in JavaScript is a feature that allows you to extract values from arrays or properties from objects and assign them to distinct variables in a readable way. It simplifies extracting data from complex structures.

1. Array Destructuring

examples:- const fruits = ["apple", "banana", "cherry"]; // Unpacking values into variables const [first, second, third] = fruits; console.log(first,second,third); // Output: "apple", "banana", "cherry" //Skipping Values: const [first, , third] = fruits; console.log(first, third); // Output: "apple", "cherry" //Using Rest with array const [first, ...others] = fruits; console.log(first); // Output: "apple" console.log(others); // Output: ["banana", "cherry"]

2. Object Destructuring

examples:- const person = { name: "Alex", age: 25, country: "USA" }; // Unpacking properties into variables const { name, age, country } = person; console.log(name, age, country); // Output: Alex 25 USA //we need to use same key names if we are not using renaming //Renaming Variables: const { name: fullName, age: years, country } = person; console.log(fullName); // Output: "Alex" console.log(years, country); // Output: 25 USA //Default Values: const { gender = "Not specified", city: place = "Not known" } = person; console.log(gender); // Output: "Not specified" console.log(city); // Output: "Not known" //used renaming with default values //Using Rest with Object: const { name, ...details } = person; console.log(name); // Output: "Alex" console.log(details); // Output: { age: 25, country: "USA" }

3. Nested Destructuring

examples:- const student = {   name: "Emma",   marks: { math: 90, science: 85 } }; const {   marks: { math, science } } = student; console.log(math); // Output: 90 console.log(science); // Output: 85

DOM

Document Object Model(DOM)

The DOM is essentially a representation of a webpage that a browser creates when it loads an HTML document. The DOM is a tree-like structure that represents the elements of a webpage as nodes. Each element (such as paragraphs, images, and headings) becomes an object that scripts can access and modify. tree

Document Object - The document object is the entry point to the DOM, representing the whole webpage in the browser. It allows JavaScript to dynamically access, modify, and update page content and structure. We can print it using console.dir(document);

Finding Elements

Often, with JavaScript, you want to manipulate HTML elements. To do so, you have to find the elements first. There are several ways to do this:

getElementById

Finds a single element by its id attribute.
Returns: The element object if found, or null if no match.

Syntax:- document.getElementById("idName")
Example:- <p id="intro">Hello there!</p> let element = document.getElementById("intro"); console.log(element.textContent); // Outputs: "Hello there!" //When to use: When you know the exact id of an element.

getElementsByClassName

Finds all elements with a specific class name from the DOM.
Returns: It returns a live HTMLCollection (a dynamic list) of all elements that match the given class name. If no elements match, it returns an empty collection.

Syntax:- document.getElementsByClassName("className")
Example:- <div class="box">One</div> <div class="box">Two</div> let boxes = document.getElementsByClassName("box"); console.log(boxes[0].textContent); // Outputs: "One" console.log(boxes.length); // Outputs: 2 //When to use: When you need all elements sharing a class. Note: it’s live, so if the DOM changes, the collection updates.

getElementsByTagName

Finds all elements with a specified tag name from the DOM.
Returns: It returns a live HTMLCollection of all elements matching the given tag name. If no elements match, it returns an empty collection.

Syntax:- document.getElementsByTagName("tagName")
Example:- <p>First</p> <p>Second</p> let paragraphs = document.getElementsByTagName("p"); console.log(paragraphs[1].textContent); // Outputs: "Second"

Live Collection: The collection updates automatically if elements are added or removed.
Array-Like: It can be accessed using indices ([0], [1]), but it's not a real array.

querySelector

Finds the first matching element from the DOM based on a CSS selector. It is widely used and powerful, allowing you to use any valid CSS selector to target elements.
Returns: The first matching element, or null if no match.

Syntax:- document.querySelector("selector") Notes: You can use any CSS selector—like #id, .class, tag, or even [attribute="value"] e.t.c
Example:- <div id="main">Main Div</div> <p class="text">Paragraph 1</p> <p class="text">Paragraph 2</p> const mainDiv = document.querySelector('#main'); // Select by ID const firstParagraph = document.querySelector('.text'); // Select first element with class 'text' console.log(mainDiv.textContent); // Output: "Main Div" console.log(firstParagraph.textContent); // Output: "Paragraph 1"

querySelectorAll

Finds all matching elements from the DOM based on a CSS selector.
Returns: A NodeList (a static list-like object) of matching elements. If no matching elements are found, it returns an empty NodeList.

Syntax:- document.querySelectorAll("selector") Notes: You can use any CSS selector.
Example:- <ul>   <li class="item">Item 1</li>   <li class="item">Item 2</li>   <li class="item">Item 3</li> </ul> const items = document.querySelectorAll('.item'); console.log(items.length); // Output: 3 // Loop through all selected elements items.forEach(item => {   console.log(item.textContent); // Output: "Item 1", "Item 2", "Item 3" });

Returns a Static NodeList: This method returns a static list. It does not update automatically if the DOM changes.
Array-Like: The returned NodeList is array-like and can be iterated using forEach(), but it does not have all array methods like map() or filter().

Content Manipulation

innerText, textContent, and innerHTML e.t.c are properties used to get or set the content of HTML elements. They have different behaviors and use cases.

1. innerText

Gets or sets the visible text content of an element, ignoring hidden elements, script/style tags, and HTML markup.
Behavior: It reflects what a user actually sees on the page, taking CSS visibility into account (e.g., it skips text with display: none).

Example:- <div id="example">   Hello <span style="display:none">hidden</span> World! </div> let div = document.getElementById("example"); console.log(div.innerText); // Outputs: "Hello World!" div.innerText = "New <b>text</b>"; // Replaces content with "New <b>text</b>" // As we have used <b> tag but it not works because innerText works with plain text and ignores HTML tags.

2. textContent

Gets or sets the raw text content of an element, including all text within it (even hidden elements and script/style tags), but without interpreting HTML.
Behavior: It grabs everything as plain text, ignoring visibility or rendering rules.

Example:- <div id="example">   Hello <span style="display:none">hidden</span> World!   <script>var x = 1;</script> </div> let div = document.getElementById("example"); console.log(div.textContent); // Outputs: "Hello hidden World!\n    var x = 1;" div.textContent = "New <b>text</b>"; // Replaces all content with "New <b>text</b>" //Here also <b> tag is treated as text, not HTML.

3. innerHTML

Gets or sets the HTML content of an element, including tags, as a string. When setting it, the browser parses the string as HTML.
Behavior: It deals with markup, not just text, so you can add or manipulate elements and their structure.

Example:- <div id="example"> Hello <b>World!</b> </div> let div = document.getElementById("example"); console.log(div.innerHTML); // Outputs: "Hello <b>World!</b>" div.innerHTML = "New text"; // Replaces content with "New text" , recognise html also //other way to add style to same present text div.innerHTML = `<u>${div.innerText}</u>`; //underline same text

When to use: When you need to work with HTML structure (e.g., adding tags, elements, or styling).
Note: Be cautious when setting innerHTML with user input—it can lead to security issues like XSS (cross-site scripting) if not sanitized.

Attribute Manipulation

The DOM provides several methods to get, set, check, or remove attributes.

1. getAttribute()

Retrieves the value of a specified attribute from an element.
Returns: The attribute's value as a string, or null if it doesn't exist.

Syntax:- element.getAttribute("attributeName")
Example:- <img id="pic" src="image.jpg" alt="A picture"> let img = document.getElementById("pic"); console.log(img.getAttribute("src")); // Outputs: "image.jpg" console.log(img.getAttribute("title")); // Outputs: null (not set)

2. setAttribute()

Sets or updates the value of an attribute on an element.
Behavior: If the attribute exists, it updates it; if not, it creates it.

Syntax:- element.setAttribute("attributeName", "value")
Example:- <div id="box">Content</div>; let div = document.getElementById("box"); div.setAttribute("class", "highlight"); div.setAttribute("id", "123"); console.log(div.outerHTML); // Outputs: <div id="123" class="highlight">Content</div> When to use: To add or modify any attribute,

3. hasAttribute()

Checks if an element has a specific attribute.
Behavior: true if the attribute exists, false if not (even if it's empty).

Syntax:- element.hasAttribute("attributeName")
Example:- <button id="btn" disabled>Click me</button> let btn = document.getElementById("btn"); console.log(btn.hasAttribute("disabled")); // Outputs: true

4. removeAttribute()

Removes a specified attribute from an element.

Syntax:- element.removeAttribute("attributeName")
Example:- <p id="text" style="color: blue">Hello</p> let p = document.getElementById("text"); p.removeAttribute("style"); console.log(p.outerHTML); // Outputs: <p id="text">Hello</p>

5. Using Properties Directly

For standard attributes (like id, className, src, value), you can access or modify them as properties of the element object.
Behavior: These are often more convenient than getAttribute/setAttribute, but they only work for well-known attributes.

Example:- <input id="field" type="text" value="Initial"> let input = document.getElementById("field"); console.log(input.value); // Outputs: "Initial" input.value = "Updated"; // Changes the value console.log(input.type); // Outputs: "text" //Special Case - className: input.className = "form-field"; // Sets class attribute console.log(input.className); // Outputs: "form-field" When to use: For common attributes where direct property access is simpler and faster.

6. Working with data-* Attributes

Custom attributes prefixed with data- can be accessed via the dataset property.

Syntax:- element.dataset.key (where key is the part after data-).
Example:- <div data-type="product">Item</div> let div = getElementsByTagName("div"); console.log(div.dataset.type); // Outputs: "product" div.dataset.status = "active"; // Adds data-status="active" console.log(div.outerHTML); // Outputs: <div data-type="product" data-status="active">Item</div>

Style Manipulation

Style property

The style property in JavaScript allows you to directly manipulate the inline CSS styles of an HTML element. You access the style property through the DOM (Document Object Model) by selecting an element.

Syntax:- element.style.propertyName; //just accessing element.style.property = "value"; //assigning value You can set styles using camelCase for properties that have hyphens (-) in CSS. like background-color changes to backgroundColor
Examples:- <div id="box">Hello, World!</div> //1. Setting styles let box = document.getElementById("box"); box.style.backgroundColor = "yellow"; // Background color box.style.border = "2px solid black"; // Border //2. Getting Styles console.log(box.style.fontSize); // Output: "20px" Note: It won't read styles from external CSS files or stylesheets. //3. Removing Styles To remove an inline style, set it to an empty string. box.style.color = ""; // Removes the inline color style //4. Multiple Styles Using Object.assign Object.assign(box.style, {   padding: "10px",   margin: "15px",   borderRadius: "5px" });

Limitations: It only affects inline styles, not styles from external CSS files or <style> tags unless overridden.

classList property

The classList property is a read-only property that returns a live collection (DOMTokenList) of the class names assigned to an HTML element. It provides methods to easily add, remove, toggle, and check class names.

Common Methods of classList
1 add(className) — Adds a new class
2 remove(className) — Removes an existing class
3 toggle(className) — Adds the class if not present; removes it if present
4 contains(className) — Checks if the class exists (returns true or false)
5 replace(oldClass, newClass) — Replaces an existing class with a new one

Syntax:- element.classList; //with its methods like add,remove,toggle, contains element.classList.methodName("className") // for replace Replace: element.classList.replace("oldClass", "newClass")
Examples:- <div id="box" class="container active">Hello, World!</div> let box = document.getElementById("box"); //1. Accessing class list console.log(box.classList); // Output: DOMTokenList ["container", "active"] //2. Adding a class box.classList.add("highlight"); //3. Removing a class box.classList.remove("active"); //4. Toggling a class box.classList.toggle("hidden"); // Adds "hidden" if not present, otherwise removes it //5. Checking if a class exists console.log(box.classList.contains("container")); // Output: true //6. Replacing a class box.classList.replace("container", "new-container");

The classList property is useful for dynamically applying or modifying styles defined in external stylesheets or CSS files.

DOM Navigation

DOM Navigation

DOM navigation refers to moving between elements in the HTML structure (like a family tree) using properties of DOM nodes.
This is useful for manipulating elements, including styles or classes, without relying solely on selectors like querySelector.

Some nevigation properties
parentElement Access the parent of an element. Returns an Element object or null if there's no parent element
children Returns a live HTMLCollection of all child elements of an element Type: HTMLCollection (array-like but not a true array; iterable using loops like for...of).
nextElementSibling Returns the next sibling that is an element Returns an Element object or null if there's no next element sibling.
previousElementSibling Returns the previous sibling that is an element Returns an Element object or nullif there's no previous element sibling.
Many other may also there...

Syntax:- element.property; e.g - element.parentElement;
Examples:- <div id="container">   <p>First</p>   Text between   <p id="target">Second</p>   <p>Third</p> </div> const target = document.getElementById("target"); // parentElement console.log(target.parentElement); //Output: <div id="container"> // children (of the parent) console.log(target.parentElement.children); //Output: [<p>First</p>, <p>Second</p>, <p>Third</p>] // nextElementSibling console.log(target.nextElementSibling); //Output: <p>Third</p> // previousElementSibling console.log(target.previousElementSibling); //Output: <p>First</p> //there are more also...

Create Elements

document.createElement()

To create elements using JavaScript, you can use the document.createElement() method.

Syntax:- document.createElement("tagName") //returns a new html element
Example:- //1. Create a new element const div = document.createElement('div'); //creates a new div element //2. Add content (Content Manipulation) div.textContent = 'Hello World'; //using textContent,innerHTML... //3. Add attributes (Attribute Manipulation) div.id = 'myDiv'; div.className = 'container'; //4. Add it to the document (using append) document.body.appendChild(div); Steps ~ Create - Add content - Add attributes - Append to show on page.

Append/Add Elements

Appending elements means adding new HTML elements (like <div>, <p>, etc.) to an existing part of the webpage (DOM). JavaScript offers several methods to append elements in various ways:

1. append()

Appends multiple elements or strings as the last children of the parent. More flexible than appendChild() because it accepts multiple arguments and can also used to add strings.

Syntax:- parent.append(child or "string") // to append multiple parent.append(...children or "string") parent.append(child1, child2 or "string1", "string2") //...children - One or more elements, or strings (using spread operator)
Example:- <div id="container">Previous content</div> //1. Append string content at the end const container = document.getElementById("container"); container.append(" Text using append", " and more text"); console.log(container.textContent); //Output: "Previous content Text using append and more text" //2. to add element as last children const span = document.createElement("span"); //creates span span.textContent = " - Appended Span"; //adds content container.append(span); //appends span

2. appendChild()

Adds a single element as the last child of the parent element. Only works with a single element (not multiple elements or strings).

Syntax:- parent.appendChild(child)
Example:- const parent = document.createElement('div'); //creates a div element const child = document.createElement('p'); //creates a p element child.textContent = 'I am the child'; //add content to p parent.appendChild(child); // Adds <p> as last child of div // Append the entire div (with its child) to the body of the document document.body.appendChild(parent); //Resulting structure:- <body>   other elements if present....   <div>     other elements if present....     <p>I am the child</p>   </div> </body>

3. prepend()

Adds multiple elements or strings as the first children of the parent. Similar to append(), but inserts at the beginning.

Syntax:- parent.prepend(child or "string") // to append multiple parent.prepend(...children or "string") parent.prepend(child1, child2, "string1", "string2" e.t.c) //...children - One or more elements, or strings (using spread operator)
Example:- <div id="container">Existing Content</div> const container = document.getElementById("container"); // Create an <h2> element const heading = document.createElement("h2"); heading.textContent = "Prepended Heading"; // Create a <p> element with string content const paragraph = document.createElement("p"); paragraph.textContent = "Additional Info - "; //1. prepend() to add a string to the p element in front paragraph.prepend("More Details Here - "); //2. Prepend both elements to the container container.prepend(heading, paragraph); //Resulting structure:- <div id="container">   <h2>Prepended Heading</h2>   <p>More Details Here - Additional Info</p>   Existing Content </div>

4. insertAdjacentElement()

Inserts a single element at a specific position relative to the target element. Not able to add string directly like append().

Syntax:- element.insertAdjacentElement("position", newElement)

position parameter values
'beforebegin' insert before the element itself
'afterbegin' insert inside the element, before its first child
'beforeend' insert inside the element but, after its last child
'afterend' insert after the element itself

Example:- <div id="container">Original Content</div> // 1. "beforebegin" — Before the target element itself const para1 = document.createElement("p"); para1.textContent = "Inserted Paragraph - beforebegin"; box.insertAdjacentElement("beforebegin", para1); // 2. "afterbegin" — As the first child of the target element const para2 = document.createElement("p"); para2.textContent = "Inserted Paragraph - afterbegin"; box.insertAdjacentElement("afterbegin", para2); // 3. "beforeend" — As the last child of the target element const para3 = document.createElement("p"); para3.textContent = "Inserted Paragraph - beforeend"; box.insertAdjacentElement("beforeend", para3); // 4. "afterend" — After the target element itself const para4 = document.createElement("p"); para4.textContent = "Inserted Paragraph - afterend"; box.insertAdjacentElement("afterend", para4); //Resulting structure:- <p>Inserted Paragraph - beforebegin</p>   <div id="box">     <p>Inserted Paragraph - afterbegin</p> //afterbegin     Original Content     <p>Inserted Paragraph - beforeend</p>   </div> <p>Inserted Paragraph - afterend</p>

there may other methods to append elements or strings....

Removing Elements

Removing elements in JavaScript refers to the process of deleting an HTML element or its content from the Document Object Model (DOM). This can be achieved using various methods like remove(), removeChild(), and innerHTML = "" e.t.c, depending on the specific requirement.

1. removeChild()

Removes a specified child element from its parent. You need a reference to both the parent and the child element.

Syntax:- parent.removeChild(childElement) child - The element to remove (must be a direct child of the parent)
Syntax:- const parent = document.getElementById("list"); //selecting parent const child = document.getElementById("listItem"); //selecting child parent.removeChild(child); // Removes the selected child from the parent

2. remove()

Removes the element directly from the DOM without needing a reference to its parent. Simpler than removeChild().

Syntax:- element.remove()
Syntax:- const element = document.getElementById("item"); element.remove(); // Removes the element directly e.g const body = document.getElementsByTagName("body"); body.remove(); // removes body element //use it carefully

3. innerHTML = ""

Clears all content inside an element by setting its innerHTML to an empty string. Usage: When you want to remove all child elements and text inside a container.

Syntax:- element.innerHTML = ""; //just set it to empty string
Syntax:- const container = document.getElementById("content"); container.innerHTML = ""; // Clears all content inside with elements

also There are many other ways to remove elements...

DOM Events

DOM events are actions that happen in a web page, either due to user interaction or browser behavior, such as clicks, key presses, form submissions, etc. These events can be captured and handled using JavaScript.

Types of Events in JavaScript

A variety of events occur in JavaScript, categorized into different types:

Event Type Event Name Description
Mouse Events click Triggered when the user clicks an element.
dblclick Triggered when the user double-clicks an element.
mousedown Triggered when a mouse button is pressed down.
mouseup Triggered when a mouse button is released.
mousemove Triggered when the mouse moves over an element.
mouseenter Triggered when the mouse enters an element.
Keyboard Events keydown Triggered when a key is pressed down.
keyup Triggered when a key is released.
keypress Triggered when a key is pressed and released.
Form Events submit Triggered when a form is submitted.
change Triggered when an input field's value is changed.
input Triggered whenever the value of an input field changes.
focus Triggered when an input field gains focus.
blur Triggered when an input field loses focus.
Window Events load Triggered when the page has fully loaded.
resize Triggered when the browser window is resized.
scroll Triggered when the user scrolls the page.
unload Triggered when the page is about to be unloaded.
Clipboard Events copy Triggered when the user copies content.
cut Triggered when the user cuts content.
paste Triggered when the user pastes content.
Drag & Drop Events dragstart Triggered when the user starts dragging an element.
dragover Triggered when an element is dragged over a valid drop target.
drop Triggered when an element is dropped onto a valid target.
Other Events contextmenu Triggered when the user right-clicks to open the context menu.
touchstart Triggered when a touch gesture starts (for mobile devices).
touchend Triggered when a touch gesture ends.
There are many many more events also...

Ways to use Events

Events in JavaScript can be handled in multiple ways, ranging from inline event handlers to advanced event delegation. Below are the different ways you can use events in JavaScript:

1. Inline Event Handlers

This is when you add event handlers directly in the HTML using attributes like onclick, onmouseenter, etc. Write the event attribute in the HTML tag and assign it a JavaScript expression or function call.

Examples:- syntax like:- <button onclick="functionName or code here">Click Me</button> // works on any elements according to attributes //e.g 1:- <button onclick="alert('Clicked!')">Click Me</button> //e.g 2:- <div onmouseenter="this.style.background='blue'"   onmouseleave="this.style.background='white'"   style="width: 100px; height: 100px;">Hover over me</div>

2. Using Event Properties

Select the element with JavaScript and set its event property to a function.

Examples:- <div id="myDiv" style="width: 100px; height: 100px;"></div> //js code:- //1. select element using selectors const div = document.getElementById('myDiv'); //2. assign function on events div.onmouseenter = function() {   this.style.background = 'green'; }; div.onmouseleave = function() {   this.style.background = ''; }; cons - Overwrites any previous handler for that event (only one function at a time).

3. Using addEventListener() (Best Practice)

The modern, preferred method. You use addEventListener() to attach events programmatically. Select an element and call addEventListener(event, function) to bind the event. Multiple listeners can be added to the same event.

Syntax:- element.addEventListener(event, function); //function youcan declare directly or write function Name
Examples:- <button id="myButton">Click Me</button> //js code const button = document.getElementById('myButton'); //1.select //2. add event Listner button.addEventListener('click', () => {   alert('First click action!'); }); //second event Listner on same element(can be multiple) button.addEventListener('click', () => {   console.log('Second click action!'); });
Examples:- Using named functions makes it easier to remove event listeners. <button id="btn">Click Me</button> // js code function handleClick() {   alert("Button Clicked!"); } //1. select let btn = document.getElementById("btn"); //2. use event listner and assign named function btn.addEventListener("click", handleClick); //not use () here // Remove event listener if want btn.removeEventListener("click", handleClick);

4. Event Delegation(Handling Multiple Elements)

Instead of adding individual event listeners to multiple elements, use event delegation by adding a single event listener to a parent element. More efficient for dynamically added elements

Example:- <ul id="list">   <li>Item 1</li>   <li>Item 2</li>   <li>Item 3</li> </ul> //js code document.getElementById("list").addEventListener("click",function (event) {   if (event.target.tagName === "LI") {     alert("You clicked on " + event.target.textContent);   } }); event.target: This refers to the exact element that was clicked. tagName Property: returns the tag name of the clicked element in uppercase

There are many other ways to use Events...

this keyword in Event Listners

event listener's this keyword refers to the same element that triggered the event (i.e., the element to which the event listener is attached).

Example:- <button id="btn">Button</button> <p id="pera">Peragraph</p> //common function for any element using this function handleClick() {   alert("You clicked on " + this.textContent);   // 'this' refers to the element that triggered the event } document.getElementById("btn").addEventListener("click", handleClick); document.getElementById("pera").addEventListener("click", handleClick); //console.log 'this' just for explanation that what it refers to <div id="div">Div</div> div.getElementById("div").addEventListener("click", function() {   console.log(this); //Output: <div id="div">Div</div> });

event Object

The event object in JavaScript is an automatically passed argument in event handlers that contains details about the event (such as the type of event, the target element, and additional properties related to the specific event type). e.g - MouseEvent, KeyboardEvent, PointerEvent e.t.c depending on the type of event.

General Event Object Properties
Property Description
event.type Returns the event type (e.g., "click", "keydown").
event.target Returns the element that triggered the event.
event.currentTarget Returns the element where the event listener is attached.
event.clientX & event.clientY Mouse position (X, Y) relative to the viewport.
event.pageX & event.pageY Mouse position relative to the full page.
event.key Returns the key pressed (for keyboard events).
event.code Returns the physical key code (for keyboard events).
event.altKey, event.ctrlKey, event.shiftKey Returns true if these modifier keys were held.
event.preventDefault() Prevents the default action of an event (e.g., stopping form submission).
event.stopPropagation() Stops the event from bubbling up to parent elements.

Example:- //exmample related to keywoard events <input type="text" id="inputBox" placeholder="Type something..." /> let input = document.getElementById("inputBox"); document.addEventListener("keydown", function(event) {   console.log(event.key); //output like "a", "z" e.t.c   console.log(event.code); //output like "keyA", "keyZ","ArrowDown" e.t.c }); //practical example let inp = document.querySelector("inputBox"); inp.addEventListener("keydown", function (event) {   if (event.code === "KeyU") {     console.log("Character moves up");   } else if (event.code === "KeyD") {     console.log("Character moves down");   } //e.t.c });

used to track user interactions like key presses, mouse actions, form submissions, scrolling, and more. e.g - in games we have to track ArrowDown, ArrowUp e.t.c

preventDefault()

The preventDefault() method prevents the default behavior of an event in JavaScript.It is commonly used in forms, links, key presses, and context menus.
Use Cases: Prevent form submission, Disable right-click menu, Block copy-paste e.t.c many more things that done by default after a event occurs.

Example:- <form id="myForm" action = "/action">   <input type="text" id="name" placeholder="Enter Name">   <button type="submit">Submit</button> </form> let form = document.getElementById("myForm"); //e.g to prevent form submitting blank name form.addEventListener("submit", function (event) {   let name = document.getElementById("name").value;   if (name === "") {     event.preventDefault();     alert("Name cannot be empty!");   } }); //e.g clicking the link won't navigate to the URL document.querySelector('a').addEventListener('click', (event) => {   event.preventDefault();   console.log('Link click prevented!'); }); //there are many more use cases...

Event Bubbling

When an event (like a click, mouseover, etc.) occurs on an element, it doesn't just affect that element—it "bubbles up" through its parent elements, all the way to the root of the DOM (usually the document or window object), unless stopped.

Stopping Bubbling: Use event.stopPropagation() to prevent the event from bubbling up further.

Example:- //Without stopPropagation <div onclick="console.log('Div clicked')">   <button onclick="console.log('Button clicked')">Click me</button> </div> //Output like: If you click the button: "Button clicked" logs first (target element). "Div clicked" logs second (parent element), because the event bubbles up. //Stop Bubbling(with stopPropagation) button.addEventListener('click', (e) => {   console.log('Button clicked');   e.stopPropagation(); // Stops the event from reaching the parent }); //Now if button pressed only "Button clicked" logs

If you don't define an event listener on the parent, event bubbling still occurs, but nothing will happen at the parent level because there's no handler to respond to the event.

Call Stack

Call Stack and Breakpoints

The call stack in JavaScript is a data structure (specifically a LIFO - Last In, First Out stack) that keeps track of function calls in your program. It helps JavaScript manage the order of execution, especially when functions call other functions.

When Function is called JavaScript pushes the function onto the call stack. Once the function completes (returns a value or reaches its end), it's popped off the stack.
Single-Threaded Nature: JavaScript is single-threaded, meaning it can only process one thing at a time. The call stack reflects this by handling one function call at a time.

Visualizing:- function a() {   b(); } function b() {   c(); } function c() {   console.log("Done!"); } a(); //calling a Stack Flow: a() → Stack: [a] b() → Stack: [a, b] c() → Stack: [a, b, c] c() finishes → Stack: [a, b] b() finishes → Stack: [a] a() finishes → Stack: [] Output: "Done!"

When a function is removed from the call stack, its execution context, including all variables defined inside it, is typically removed from memory, which is why we cannot access them outside the function.
However, if those variables are referenced by a closure or another persistent reference, they may remain in memory even after the function is popped off the stack.

Breakpoints

Breakpoints are intentional stopping points in your code that you set while debugging. They pause the execution of your JavaScript program at a specific line, allowing you to inspect the state of the program—like variable values, the call stack, and scope—at that moment. They're a key tool in developer tools (e.g., Chrome DevTools, VS Code debugger) to troubleshoot and understand code behavior.
Setting Breakpoints:-
1. In Browser DevTools: Open the "Sources" tab, navigate to your script, and click the line number where you want to pause. breakpoints
2. Programmatically: Use the debugger statement in your code, which acts like a breakpoint when DevTools is open.

Types of Breakpoints: Line Breakpoint, Conditional Breakpoint, Function Breakpoint, Exception Breakpoint, Watchpoint (Variable Breakpoint). and many other also...
We will study and use breakpoints while debugging...

Single Threaded

Single-Threaded

JavaScript is single-threaded, meaning it has one call stack and can only execute one piece of code at a time. This design simplifies some aspects of programming but introduces challenges, especially when dealing with time-consuming tasks or concurrency.

Event Loop: Asynchronous operations (e.g., timers, network requests) are offloaded to the browser or Node.js runtime, which uses additional threads internally, but the JavaScript code itself runs on one thread via the event loop.

Problems with Single-Threaded Nature
Blocking the Thread Long-running synchronous tasks (e.g., heavy computation) block the call stack, freezing the application.
Poor Responsiveness In browsers, a blocked thread prevents UI updates, event handling (e.g., clicks), or animations, leading to a "janky" user experience.
Limited Concurrency You can't run multiple tasks in parallel on the JavaScript thread, unlike multi-threaded languages (e.g., Java).
Asynchronous Complexity To avoid blocking, JavaScript relies on asynchronous patterns (callbacks, promises, async/await), which can lead to "callback hell" or complex code flows.

Solutions to Single-Threaded Problems
Asynchronous Programming Offload time-consuming tasks to asynchronous APIs, letting the event loop handle them without blocking the thread.
Web Workers (Browsers) Run heavy computations in separate threads using Web Workers, which operate outside the main JavaScript thread.
How It Works: Workers run in parallel, communicating with the main thread via message
Worker Threads (Node.js) Similar to Web Workers, Node.js offers the worker_threads module for parallel execution.
Chunking or Batching Break long tasks into smaller chunks and process them incrementally using setTimeout or requestAnimationFrame to avoid blocking.

Callback Hell

Callback hell

Callback hell in JavaScript refers to a situation where multiple nested callbacks make the code hard to read, maintain, and debug. It often happens when dealing with asynchronous operations, like fetching data or handling events, where each step depends on the result of the previous one.

Example:- function step1(callback) {   setTimeout(() => {     console.log("Step 1 completed");     callback();   }, 1000); } function step2(callback) {   setTimeout(() => {     console.log("Step 2 completed");     callback();   }, 1000); } function step3(callback) {   setTimeout(() => {     console.log("Step 3 completed");     callback();   }, 1000); } // Nested Callbacks (Callback Hell) step1(() => {   step2(() => {     step3(() => {       console.log("All steps completed");     });   }); });

Problems with Callback Hell :-
1.Difficult to Read & Maintain - Code becomes messy due to deep nesting.
2.Hard to Debug - If an error occurs, tracing the issue through nested callbacks is difficult.
3.Pyramid of Doom - The nested structure makes the code look like a pyramid, reducing clarity. e.t.c

How to Fix Callback Hell - Promises, Async/Await, Modularize e.t.c

Promises

Promises in JavaScript

A Promise in JavaScript is an object that represents the eventual completion or failure of an asynchronous operation. It helps avoid callback hell and makes asynchronous code more readable.

Promise States -
State Description
Pending The operation is still in progress.
Fulfilled (Resolved) The operation completed successfully.
Rejected The operation failed.

Example:- function saveToDb(data) {   return new Promise((resolve, reject) => {     let internetSpeed = Math.floor(Math.random() * 10) + 1;     if (internetSpeed > 5) {       resolve("Success: Data was saved");     } else {       reject("Failure: Weak connection");     }   }); } // Testing the Promise saveToDb("User Data"); Why Use Promises :- Avoids Callback Hell, Improves Readability, Easier Error Handling e.t.c Promises make asynchronous code more manageable.

.then() and .catch() in Promises

.then() and .catch() are used to handle Promises in JavaScript - .then() Executes when the Promise is resolved (fulfilled), .catch() Executes when the Promise is rejected (failed).

Example:- function fetchData() {   return new Promise((resolve, reject) => {     let success = Math.random() > 0.5; // 50% chance of success     setTimeout(() => {       if (success) {         resolve("Data fetched successfully!");       } else {         reject("Error: Failed to fetch data!");       } // we can also skip reject if not needed     }, 1000);   }); } // Handling Promise with .then() and .catch() fetchData()   .then((result) => console.log(message)) // Runs if resolved   .catch((error) => console.log(error)); // Runs if rejected // Here, 'result' is the resolve value, and // 'error' is the reject value (both are optional) //Other syntax also possible...

Promise Chaining

Promise chaining is a technique where multiple .then() methods are linked together to execute asynchronous tasks in a sequence.

Example:- function saveToDb(data) {   return new Promise((resolve, reject) => {     let internetSpeed = Math.floor(Math.random() * 10) + 1;     if (internetSpeed > 5) {       console.log(`"${data}" saved to database`);       resolve();     } else {       reject("Promise was rejected: Weak connection");     }   }); } // Promise chaining with multiple then() a Single catch() saveToDb("Hello 1")   .then(() => {     console.log("Data1 saved.");     return saveToDb("Hello 2"); // Returning ensures chaining   })   .then(() => {     console.log("Data2 saved."); //we can use multiple then()     return saveToDb("Hello 3");   })   .then(() => {     console.log("Data3 saved.");   })   .catch(() => {     console.log("Promise was rejected."); // Handles errors for all   }); If any step fails, .catch() runs and stops further execution, meaning any steps after the rejected promise will not run. // we can also skip catch() if not needed //Other syntax also possible...

Async Functions

async and await

An async function is a special type of JavaScript function that always returns a Promise, whether you explicitly return one or not. An async function lets you write asynchronous code that looks and behaves like synchronous code using the await keyword.

Syntax:- async function functionName() {   // you can use await inside here } //syntax like normal functions just use async keyword before //Other syntax also possible...
Example:- async function sayHi() {   return "Hi there!"; } sayHi().then(value => console.log(value)); // "Hi there!" //If you return a plain value , JS wraps it in a resolved promise. // Or get value in another async function: async function main() {   let message = await sayHi();   console.log(message); // "Hi there!" } main();

await keyword - The await keyword can only be used inside an async function.
It tells JS to: Wait for the Promise to resolve, Then move to the next line of code.
It lets you wait for a promise to resolve without nesting .then() calls.

Example:- async function getData() {   let data = await fetchData();   console.log(data); // runs after fetchData() is resolved } //we can also use await without assigning it to a variable! //like - await fetchData(); //await makes asynchronous code behave like synchronous code //easier to write and read!

Handling Rejections

Async functions handle errors gracefully with try...catch, just like synchronous code:

Syntax:- async function mightFail() {   try {     let response = await fetch("https://bad-url.com");     let data = await response.json();     return data;   } catch (error) {     console.error("Oops:", error);   }   //other code here } //If we don't handle errors properly, the rest of the code may not execute when an error occurs.

APIs

API

An API (Application Programming Interface) is a set of rules that allows one software application to communicate with another. It defines how requests and responses should be structured, making integration between different systems possible.

How They Work

  • An API exposes specific "endpoints" (like URLs or functions) that a program can call.
  • You send a request (e.g., "Give me the weather for New York") in a format the API understands (often HTTP with JSON or XML).
  • The API processes it and sends back a response (e.g., "It's 72°F and sunny").

Sending Requests

Sending a request means your application (client) contacts a server (API) and asks for something — like data, a save operation, update, or deletion. The server then responds with data or a status.

1. fetch()
fetch() is a JavaScript function built into modern browsers that allows you to make HTTP requests to fetch resources (like data, images, etc.) from a server or API. It returns a Promise.

Syntax:-    Using Javascript fetch():- let url = "https://catfact.ninja/fact"; fetch(url) // [1] .then((res) => {   console.log("Raw Response:", res); // [2]   return res.json(); // [3] })   .then((data) => {   console.log("Cat Fact:", data.fact); // [4] })   .catch((err) => {   console.log("ERROR -", err); // [5] }); //Explanation:- 1. fetch(url) - What it does: Sends a GET request, What you get: A Promise that resolves to a Response object. 2. .then((res) => { ... }) - res is the Response object. console.log("Raw Response:", res); will output: Raw Response: Response { type: 'cors', url: 'https://catfact.ninja/fact', status: 200, ... } 3. return res.json(); Converts the response body from JSON into a usable JavaScript object. Returns another Promise, which resolves to the actual data. 4. .then((data) => { ... }) data is the parsed JSON object from the API. You'll get something like: {   "fact": "Cats sleep for 70% of their lives.",   "length": 35 } console.log("Cat Fact:", data.fact); outputs: Cat Fact: Cats sleep for 70% of their lives. 5. .catch((err) => { ... }) - Catches any network error
Example 2:- Javascript fetch() with async and await:- let url = "https://catfact.ninja/fact"; async function getFacts() {   try {     let res = await fetch(url);     let data = await res.json();     console.log("Fact 1:", data.fact);   } catch (e) {     console.log("error -", e);   } } getFacts();

2. axios()
Axios is a JavaScript library used to send HTTP requests from the browser or Node.js to a server or API. It automatically parses json data.
we need to install it (using - npm install axios)
OR add this <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

Example:- const axios = require('axios'); // Only in Node.js, not needed in browser let url = "https://catfact.ninja/fact"; axios.get(url) .then((response) => {   console.log("Response:", response.data.fact); //It automatically parses }) .catch((error) => {   console.log("Error:", error); }); example sending headers using asios:- const url = "https://icanhazdadjoke.com/"; async function getJokes() {   try {     // make object with key - headers, and in value make another object     const config = { headers: { Accept: "application/json"} };     //pass headers object as 2nd argument     let res = await axios.get(url, config);     console.log(res.data);   } catch (err) {     console.log("Error:", err);   } }

Types of APIs

  • Web APIs: Most common today, accessed over the internet (e.g., Twitter API, Google Maps API).
  • RESTful APIs: A popular style of web API using standard HTTP methods (GET, POST, etc.), known for being simple and scalable.
  • Library APIs: Built into programming languages or frameworks (e.g., Python's os module).
  • Operating System APIs: Let apps interact with your computer (e.g., Windows API).
  • Operating System APIs: APIs provided by the OS (e.g., Windows API, Linux syscalls). other type may also

How Developers Use APIs

  • Get an API key: (if required) to authenticate requests.
  • Read the API's documentation: to learn its endpoints and rules.
  • Write code to send requests: (e.g., using JavaScript's Fetch API, Python's requests library etc., to send requests and handle responses).

API testing tools

  • Postman - A very popular and beginner-friendly tool used to test RESTful APIs. Supports GET, POST, PUT, DELETE requests and more. You can also automate tests and save collections.
  • Hoppscotch - A fast, open-source alternative to Postman. Web-based, supports REST, GraphQL, and WebSocket testing. No need to download/sign up can use directly for quick usage.
  • There are many more tools also we can learn them accordingly...

Why They're Useful and Real-World Examples

Efficiency: Developers can use pre-built services instead of coding everything from scratch.
Interoperability: Apps can share data—like how your weather app pulls data from a weather service.
Modularity: Keeps systems separate but connected, making updates easier.

Examples: Social Media(e.g X API lets developers pull posts or user info), Maps(e.gGoogle Maps API lets apps show locations or calculate routes), Payments(e.g Stripe's API lets websites process credit card payments), e.t.c

JSON

JSON

JSON stands for JavaScript Object Notation. It is a lightweight data-interchange format, easy for humans to read and write and easy for machines to parse and generate. JSON is often used to exchange data between a client and a server in web applications.

File extension - .json

JSON Syntax Rules

  • Data is in name/value pairs.
  • Data is comma-separated.
  • Curly braces {} hold objects.
  • Square brackets [] hold arrays.
  • Names (keys) must be strings (in double quotes).
  • Values can be:
    • String ("text")
    • Number, Float (10, 3.14)
    • Object ({})
    • Array ([])
    • Boolean (true or false)
    • null
Example:- {   "name": "Jonn",   "age": 32,   "isStudent": true,   "skills": ["HTML", "CSS", "JavaScript"],   "address": {     "city": "Jalandhar",     "state": "Punjab"   } } //generally like in one-line {"id": 101, "name": "John", "isStudent": true, "score": 88.5}

JSON vs JavaScript Object

Feature JSON JavaScript Object
Quotes on keys Required Optional
Comments Not allowed Allowed
Single quotes Not allowed Allowed
Data format Text only Executable code structure

Accessing JSON Data

When data comes from an API, it usually arrives in string format — even though it looks like a JavaScript object. To use it, we must convert it into an actual JavaScript object.

like:- let JsonResponse = '{"id": 101, "name": "John", "score": 88.5}'

JSON.parse()

JSON.parse() is a JavaScript method that takes a JSON string and converts it into a JavaScript object so that you can access it like javascript object.

Example:- const jsonString = '{"name": "John", "age": 20}'; const data = JSON.parse(jsonString); console.log(data); // Output: {"name": "John", "age": 20} console.log(data.age); // Output: 20 //use it when you receive data from an API (because it's usually in string format).

JSON.stringify()

JSON.stringify() is a JavaScript method that takes a JavaScript object and converts it into a JSON string so that it can be sent to a server or stored.

Example:- const user = {   name: "John",   age: 20 }; const jsonString = JSON.stringify(user); console.log(jsonString); // Output: '{"name":"John","age":20}' //use it when you want to send data to a server or save it in local storage.

Ajax

Ajax

AJAX (Asynchronous JavaScript and XML) is a technique used in web development to send and receive data from a server without reloading the entire page. Despite the name, AJAX can work with JSON, XML, HTML, or plain text — not just XML.


Key features of Ajax

  • Allows web pages to update dynamically
  • Avoids full page reload
  • Communicates with the server in the background
  • Often used in forms, search suggestions, live updates, etc.
Example:- const xhr = new XMLHttpRequest(); xhr.open('GET', 'https://api.example.com/data'); xhr.onload = function () {   if (xhr.status === 200) {     console.log(xhr.responseText); // usually JSON   } }; xhr.send(); //Modern Way: AJAX with fetch() fetch('https://api.example.com/data')   .then(response => response.json())   .then(data => console.log(data))   .catch(error => console.error('Error:', error));

HTTP Verbs/ Status Codes

HTTP Verbs

HTTP verbs (also called HTTP methods) define the type of action you want to perform on a resource when communicating with a web server (usually via an API).


Common HTTP Verbs & Their Purpose:

  • GET: Retrieve data from the server (e.g., get a list of users).
  • POST: Send data to the server to create a new resource (e.g., add a new user).
  • PUT: Update an existing resource completely (e.g., replace user details).
  • PATCH: Update part of a resource (e.g., change just the user's email).
  • DELETE: Remove a resource from the server (e.g., delete a user).
  • there are other also...

HTTP Status Codes

HTTP status codes are 3-digit responses from the server that tell the client (browser or API) what happened with the request — whether it succeeded, failed, or something else.


HTTP Status Code Categories
Status Code Range Description
1xx - Informational Request received, continuing process (e.g., 100 Continue).
2xx - Success The request was successfully received, understood, and accepted (e.g., 200 OK).
3xx - Redirection Further action must be taken (e.g., 301 Moved Permanently).
4xx - Client Error The request contains bad syntax or cannot be fulfilled (e.g., 404 Not Found).
5xx - Server Error The server failed to fulfill a valid request (e.g., 500 Internal Server Error).

Common HTTP Status Codes
Status Code Description
200 OK Request was successful.
201 Created Resource successfully created (e.g., after a POST request).
204 No Content Request succeeded, but there is no content to return.
301 Moved Permanently Resource has been moved to a new URL.
400 Bad Request The request was invalid or cannot be served.
401 Unauthorized Authentication required or failed.
403 Forbidden You don't have permission to access the resource.
404 Not Found The requested resource could not be found.
500 Internal Server Error A generic error occurred on the server.
503 Service Unavailable Server is temporarily overloaded or down.

Add information in URLs

APIs often use URLs to define endpoints, and information can be added to URLs in several ways, depending on the API's design.

Path Parameters

Path parameters are placeholders in the URL path that represent specific resources or identifiers.
Use Case: Accessing a specific resource (e.g., a user by ID).

Example:- Syntax: /resource/{id} GET https://api.example.com/users/123 Here, 123 is the user ID, identifying a specific user.

Query Parameters

Query parameters are key-value pairs appended to the URL after a ?, separated by &. They're commonly used for filtering, sorting, or optional settings.
Use Case: Filtering results, pagination, or specifying options.

Example:- Syntax: ?key1=value1&key2=value2 e.t.c Example: GET https://api.example.com/users?role=admin&limit=10&sort=name

You can combine path and query parameters for complex requests.



We can manipulate an API link using variable query strings by dynamically adding key-value pairs in the URL based on user input or variables in your code.

Example:- let url = "http://universities.hipolabs.com/search?country="; let country = "Nepal"; //we can also get this variable from user e.t.c. async function getColleges() {   try {     let res = await axios.get(url + country);     console.log(res.data); // Just log the result data   } catch (e) {     console.log("Error:", e);   } }

HTTP Headers

HTTP headers are key-value pairs sent in the request or response of an HTTP transaction. In API requests, headers provide metadata about the request, such as:

  • Authentication credentials (e.g., API keys, tokens).
  • Content type of the request or response (e.g., JSON, XML).
  • Instructions for caching, compression, or behavior.
  • Unlike URL parameters or the request body, headers are not part of the URL but are included in the HTTP request's header section.
  • They're essential for secure and efficient API communication.

Example:- fetch('/api/data', {   method: 'GET',   headers: {     'Authorization': 'Bearer YOUR_TOKEN',     'Accept': 'application/json'   } });

In Console:-
header

JavaScript OOPS

Object-Oriented Programming (OOP) in JavaScript is a programming paradigm that uses objects and classes to structure code in a modular and reusable way.

Core OOP Concepts

  • Encapsulation: Bundling data (properties) and methods (functions) that operate on that data into a single unit (object or class), restricting direct access to some of an object's components.
  • Inheritance: A mechanism where one class inherits properties and methods from another, promoting code reuse.
  • Polymorphism: The ability of different classes to be treated as instances of the same class through a common interface (e.g., method overriding).
  • Abstraction: Hiding complex implementation details and exposing only the necessary parts to the user.

Some Benefits of OOPs in JavaScript includes:

  • Improved code organization (structure of code)
  • Reusability of code
  • Better maintainability of code
  • Closeness to real-world objects

Object Prototypes

In JavaScript, object prototypes are a core mechanism for implementing inheritance and sharing properties and methods between objects. JavaScript is a prototype-based language, meaning objects can inherit directly from other objects via their prototype chain.

Every JavaScript object has an associated prototype object, which it can inherit properties and methods from. The prototype is referenced via the internal [[Prototype]] property (accessible via Object.getPrototypeOf() or the deprecated __proto__). Prototypes enable inheritance, allowing objects to share behavior without duplicating code.

The prototype is itself an object, so the prototype will have its own prototype, making what's called a prototype chain. The chain ends when we reach a prototype that has null for its own prototype.

Without Prototypes example

Example:- let arr1 = [1, 2, 3]; let arr2 = [1, 2, 3]; arr1.sayHello = () => {   console.log ("hello!, i am arr"); }; arr2.sayHello = () => {   console.log("hello!, i am arr"); }; arr1.sayHello === arr2.sayHello //Output: false
//what if we access prototype methods:- 'A'.toUpperCase === 'a'.toUpperCase //Output: true // as both method refer to same function

arr.__proto__ (Reference to the Prototype)

arr.__proto__ is a reference to Array.prototype, the prototype object for all arrays. Array.prototype contains methods like push, pop, slice, forEach, etc., which all arrays inherit.

Array.prototype.__proto__ is Object.prototype (since Array.prototype inherits from Object.prototype).

We can modify predefined methods also:- // Create an array const arr = [1, 2]; // Modify the push method on Array.prototype arr.__proto__.push = function(n) {   console.log("pushing number : ", n); }; arr.push(3); //Output: pushing number : 3; //we can modify like this e.t.c.

datatype.prototype

In JavaScript, every constructor function for a built-in data type (e.g., Array, String, Number, etc.) has a prototype property, which is an object. (e.g., Array.prototype, String.prototype e.t.c, that holds the shared functionality for objects of that type.)

Array.prototype - Contains array methods like push(), pop(), map(), filter(), etc. //example:- const arr = [1, 2]; console.log(arr.__proto__ === Array.prototype); // true console.log(Array.prototype.map); // [Function: map]
String.prototype - Contains string methods like toUpperCase(), slice(), charAt(), etc. //example:- const str = 'hello'; console.log(str.__proto__ === String.prototype); // true console.log(String.prototype.toUpperCase); // [Function: toUpperCase] //there are other also...

Factory Functions

Factory Functions

A factory function is just a normal function that returns an object.

Basic Syntax:- function createUser(name, age) {   const person = {     name: name,     age: age,     greet: function () {       console.log(`Hi, I am ${name}`);     }   };   return person; //return a object } //Usage: const user1 = createUser("Inderjit", 20); const user2 = createUser("Adam", 25); user1.greet(); // Hi, I am Inderjit user2.greet(); // Hi, I am Adam

Not commonly Used - As No automatic prototype sharing, So Each object returned by the factory has its own copy of methods. This wastes memory if many objects share the same method.

Constructor Function , new keyword

Constructor Functions

A constructor function is a regular function used to create multiple objects of the same type using the new keyword.

Basic Syntax:- function User(name, age) {   this.name = name;   this.age = age;   this.greet = function () {     console.log("Hi, I am " + this.name);   }; } //Usage: const user1 = new User("Inderjit", 20); //use new operator like this const user2 = new User("Aman", 25); user1.greet(); // Hi, I am Inderjit user2.greet(); // Hi, I am Aman console.log(user1.__proto__ === User.prototype); // true console.log(user1 instanceof User); // true user1.greet === user2.greet //true - as both point to the same function in memory.

new Keyword

The new keyword is used to invoke a constructor function, creating a new object and setting up its prototype chain. When you call a function with new, JavaScript performs the following steps:

  • Creates a new empty object: {}
  • Sets the prototype: newObj.__proto__ = User.prototype
  • Binds this: Sets this to the new object within the constructor function.
  • Executes the Constructor: Runs the constructor function, initializing the object with properties/methods.
  • Returns the Object: Implicitly returns the new object (unless the constructor explicitly returns another object).

Classes

A class in JavaScript is a blueprint for creating objects with shared structure and behavior (properties and methods).

Introduced in ES6, it's syntactic sugar over JavaScript's existing prototype-based inheritance. Similar like constructor functions, but with a more intuitive syntax inspired by object-oriented programming (OOP) languages like Java or C++.

Syntax: Uses class keyword, with a constructor method for initialization and other methods defined within the class body.

Constructor: Special method to initialize object properties.

Methods: Defined without function keyword; automatically go to .prototype.

Basic Syntax and Structure:- class Person {   constructor(name, age) { //constructor method     this.name = name;     this.age = age;   }   greet() { //we can define methods like this     return `Hi, I'm ${this.name}!`;   } } let alice = new Person('Alice', 25); //use new keyword to make objects let bob = new Person('Alice', 25); //use new keyword to make objects console.log(alice.greet()); // Hi, I'm Alice! console.log(alice.__proto__ === Person.prototype); // true alice.greet === bob.greet //true - as both are same function Methods are shared (not recreated for every object).

Inheritance

Inheritance allows one class (child) to access the properties and methods of another class (parent). It promotes code reuse.

Syntax using class and extends:- class Parent {   constructor(name) {     this.name = name;   }   greet() {     console.log("Hello, I am " + this.name);   } } class Child extends Parent {   constructor(name, age) {     super(name); // calls Parent constructor     this.age = age;   }   showAge() {     console.log("I am " + this.age + " years old.");   } } const obj = new Child("Inderjit", 20); obj.greet(); // Hello, I am Inderjit (inherited from Parent) obj.showAge(); // I am 20 years old. (Child method)

extends sets up inheritance.

super() is used to call the parent class constructor.

Inherited methods come from the prototype chain.

Child class can override parent methods if needed, like:-

Overriding methods- // Parent class class Animal {   constructor(name) {     this.name = name;   }   speak() {     console.log(`${this.name} makes a sound.`);   } } // Child class class Dog extends Animal {   constructor(name, breed) {     super(name); // Call parent constructor     this.breed = breed;   }   // Overriding speak() method   speak() {     console.log(`${this.name} barks.`);   } } const a = new Animal("Animal"); a.speak(); // Output: Animal makes a sound. const d = new Dog("Tommy", "Labrador"); d.speak(); // Output: Tommy barks.
Use of super.speak():- speak() {   super.speak(); // Calls Animal's speak()   console.log(`${this.name} also barks.`); } //Output like:-- Tommy makes a sound. Tommy also barks.

super.methodName() → to call a method from the parent class.