Java Script
Java Script
1. Introduction to JavaScript
• What is JavaScript?
• History and evolution
• How JS runs in the browser (JS Engine)
• Adding JS to HTML (inline, internal, external)
3. Operators
• Arithmetic, Assignment, Comparison
• Logical operators (&&, ||, !)
• Ternary operator
• Bitwise operators
4. Control Structures
• if, else, else if
• switch
• for, while, do...while
• break, continue
5. Functions
• Function declarations vs expressions
• Parameters and arguments
• Return values
• Arrow functions
• Default, Rest, and Spread syntax
6. Arrays
• Creating arrays
• Accessing and modifying elements
• Array methods: push(), pop(), shift(), unshift(), splice(), slice()
• Iteration: for, forEach(), map(), filter(), reduce()
7. Objects
• Object literals and constructors
• Accessing and modifying properties
• Methods
• this keyword
• Nested objects
🟢 1. What is JavaScript?
JavaScript is a high-level, interpreted programming language that was originally designed to
make web pages interactive. It is now used in web development, mobile apps, desktop
applications, server-side programming (Node.js), and even IoT devices.
Key Features:
• Client-side scripting language (runs in browser)
• Lightweight and dynamic
• Supports object-oriented, functional, and event-driven programming
• Used for validations, animations, API calls, DOM manipulation, etc.
Example (Simple Alert Box):
<script>
alert("Hello, world!");
</script>
This code displays an alert popup when the page loads.
This changes the content of a paragraph dynamically when the page loads.
🔴 4. Adding JavaScript to HTML
You can include JavaScript in three ways:
a) Inline
JavaScript is written directly in an HTML element using the onclick, onmouseover, etc.
attributes.
<button onclick="alert('Button clicked!')">Click me</button>
b) Internal
JavaScript is written inside a <script> tag within the HTML file (usually in <head> or before
</body>).
<!DOCTYPE html>
<html>
<head>
<script>
function sayHello() {
alert("Hello from internal JS!");
}
</script>
</head>
<body>
<button onclick="sayHello()">Say Hello</button>
</body>
</html>
c) External
JavaScript is written in a separate .js file and linked to the HTML using the src attribute.
<!-- HTML File -->
<script src="script.js"></script>
// script.js
function greet() {
alert("Hello from external file!");
}
Then use the function in HTML:
<button onclick="greet()">Greet</button>
Project Structure:
profile-card/
│
├── index.html
├── script.js
Step 1: index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Profile Card</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
padding: 50px;
}
.card {
width: 300px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
padding: 20px;
text-align: center;
}
.hidden {
display: none;
}
</style>
</head>
<body>
<div class="card">
<h2 id="name">John Doe</h2>
<p class="hidden" id="moreInfo">Full Stack Developer. Loves pizza and cats .</p>
Step 2: script.js
function toggleInfo() {
const info = document.getElementById("moreInfo");
info.classList.toggle("hidden");
}
function changeName() {
const newName = prompt("Enter a new name:");
if (newName) {
document.getElementById("name").innerText = newName;
}
}
🔢 Variables and Data Types
🟢 1. Variables in JavaScript
A variable is a container used to store data values.
🛠️ Variable Declarations:
JavaScript has three ways to declare variables:
✅ var (ES5 - old way)
• Function-scoped
• Can be re-declared and updated
• Hoisted (moved to the top of scope but not initialized)
var name = "Alice";
var name = "Bob"; // allowed
✅ let (ES6 - modern and preferred)
• Block-scoped
• Can be updated but not re-declared in the same scope
• Not hoisted like var
let age = 25;
age = 26; // allowed
// let age = 27; Error if re-declared in the same block
✅ const (ES6 - for constants)
• Block-scoped
• Cannot be updated or re-declared
• Must be initialized at declaration
const PI = 3.1416;
// PI = 3.14; Error - Cannot reassign a const
Note: For objects/arrays, const prevents reassignment of the variable reference, not the object
itself.
✅ 2. Number
Represents both integers and floating-point numbers.
let age = 25;
let price = 9.99;
let hex = 0xff; // Hexadecimal
✅ 3. Boolean
Only two values: true or false
let isOnline = true;
let hasPermission = false;
Used in conditions:
if (isOnline) {
console.log("User is online");
}
✅ 4. Null
Represents an intentional absence of value. It’s a value that means “nothing”.
let score = null; // value is intentionally empty
✅ 5. Undefined
Represents an uninitialized variable.
let x;
console.log(x); // undefined
Also returned when accessing missing object properties:
let person = {};
console.log(person.name); // undefined
✅ 6. Symbol (ES6)
Represents a unique and immutable value, often used as object keys.
let id1 = Symbol("id");
let id2 = Symbol("id");
console.log(id1 === id2); // false
✅ 7. BigInt (ES11/ES2020)
Used for very large integers beyond the safe limit of Number.
let big = 1234567890123456789012345678901234567890n;
console.log(typeof big); // bigint
🔄 3. Dynamic Typing
JavaScript is dynamically typed, which means you don’t need to specify the variable type. The
type can even change during runtime.
let data = 42; // number
data = "forty two"; // now it's a string
data = true; // now it's a boolean
This is flexible but can cause bugs if not careful, especially with type coercion (automatic type
conversion).
3. JavaScript Operators
🟢 1. Arithmetic Operators
Used to perform mathematical operations.
Operator Description Example Result
+ Addition 5+2 7
- Subtraction 5-2 3
* Multiplication 5*2 10
/ Division 10 / 2 5
% Modulus (Remainder) 5%2 1
** Exponentiation 2 ** 3 8
++ Increment x++ x+1
-- Decrement x-- x-1
Example:
let x = 10; let y = 3;
console.log(x + y); // 13
console.log(x % y); // 1
console.log(x ** y); // 1000
🟡 2. Assignment Operators
Used to assign values to variables.
Operator Description Example
= Assign x=5
+= Add and assign x += 5 → x = x + 5
-= Subtract and assign x -= 5
*= Multiply and assign x *= 5
/= Divide and assign x /= 5
%= Modulus and assign x %= 5
Example:
let x = 10;
x += 5; // x = 15
x *= 2; // x = 30
🔵 3. Comparison Operators
Used to compare two values.
Operator Description Example Result
== Equal to (loose equality) 5 == '5' true
=== Equal value & type 5 === '5' false
!= Not equal (loose) 5 != '5' false
!== Not equal (strict) 5 !== '5' true
> Greater than 10 > 5 true
< Less than 10 < 5 false
>= Greater than or equal to 10 >= 10 true
<= Less than or equal to 5 <= 10 true
Example:
let a = 5;
let b = "5";
console.log(a == b); // true (type coercion)
console.log(a === b); // false (strict comparison)
🟣 4. Logical Operators
Used to combine multiple conditions.
Operator Description Example Result
&& Logical AND true && false false
|| Logical OR true || false true
! Logical NOT !true False
Example:
let isLoggedIn = true;
let isAdmin = false;
if (isLoggedIn && isAdmin) {
console.log("Access granted");
} else {
console.log("Access denied");
}
🟠 5. Ternary Operator
A shorthand for if...else statements.
Syntax:
condition ? expressionIfTrue : expressionIfFalse;
Example:
let age = 18;
let canVote = (age >= 18) ? "Yes" : "No";
console.log(canVote); // "Yes"
You can also nest ternary expressions:
let score = 90;
let grade = score >= 90 ? "A" : score >= 80 ? "B" : "C";
🔴 6. Bitwise Operators
These operate on binary representations of numbers.
Operator Description Example (5 & 1)
& AND 1
| OR 5
^ XOR 4
~ NOT -6
<< Left shift 5 << 1 = 10
>> Right shift 5 >> 1 = 2
Example:
console.log(5 & 1); // 1 → 101 & 001 = 001
console.log(5 | 1); // 5 → 101 | 001 = 101
console.log(~5); // -6 → ~00000101 = 11111010 (2's complement)
Bitwise operators are mainly used in low-level programming, flags, permission systems, etc.
Step 1: index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Mini Calculator</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h2> Mini Calculator</h2>
<input type="number" id="num1" placeholder="Enter first number" />
<input type="number" id="num2" placeholder="Enter second number" />
<div class="buttons">
<button onclick="calculate('+')">Add</button>
<button onclick="calculate('-')">Subtract</button>
<button onclick="calculate('*')">Multiply</button>
<button onclick="calculate('/')">Divide</button>
</div>
<div class="result">
<p id="output">Result: </p>
<p id="comparison"></p>
</div>
<button onclick="clearAll()">Clear</button>
</div>
<script src="script.js"></script>
</body>
</html>
Step 2: style.css (optional styling)
body {
font-family: sans-serif;
background: #f2f2f2;
display: flex;
justify-content: center;
padding: 40px;
}
.container {
background: white;
padding: 20px 30px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
text-align: center;
}
input {
margin: 5px;
padding: 10px;
width: 80%;
}
button {
margin: 5px;
padding: 10px 15px;
cursor: pointer;
}
.result {
margin-top: 15px;
font-weight: bold;
}
Step 3: script.js
function calculate(operator) {
let num1 = document.getElementById("num1").value;
let num2 = document.getElementById("num2").value;
// Convert to numbers
num1 = parseFloat(num1);
num2 = parseFloat(num2);
// Input validation
if (isNaN(num1) || isNaN(num2)) {
alert("Please enter valid numbers.");
return;
}
let result;
// Arithmetic operators
switch (operator) {
case '+': result = num1 + num2; break;
case '-': result = num1 - num2; break;
case '*': result = num1 * num2; break;
case '/': result = num2 !== 0 ? num1 / num2 : "Cannot divide by zero"; break;
default: result = "Invalid Operation";
}
document.getElementById("output").innerText = Result: ${result};
// Comparison + ternary
let compare = num1 === num2 ? "Both numbers are equal." : num1 > num2 ? ${num1} is
greater than ${num2} : ${num1} is less than ${num2};
document.getElementById("comparison").innerText = compare;
}
function clearAll() {
document.getElementById("num1").value = ''; document.getElementById("num2").value = '';
document.getElementById("output").innerText = 'Result:';
document.getElementById("comparison").innerText = '';
}
Example:
let age = 18;
if (age > 18) {
console.log("You can vote");
} else if (age === 18) {
console.log("You just became eligible to vote!");
} else {
console.log("You are too young to vote");
}
🟡 2. switch Statement
A cleaner alternative to multiple if...else if blocks when checking the same variable for different
values.
✅ Syntax:
switch (expression) {
case value1:
// code
break;
case value2:
// code
break;
default:
// code if no case matches
}
Example:
let day = "Monday";
switch (day) {
case "Monday":
console.log("Start of the week");
break;
case "Friday":
console.log("Almost weekend!");
break;
default:
console.log("Midweek day");
}
break is used to prevent fall-through — i.e., the next case(s) from executing unintentionally.
🔁 3. Loops
Used to repeat code multiple times.
✅ for Loop
Runs a block of code a specific number of times.
for (let i = 1; i <= 5; i++) {
console.log("Count: " + i);
}
Structure:
for (initialization; condition; increment/decrement)
✅ while Loop
Runs a block of code as long as the condition is true.
let i = 1;
while (i <= 5) {
console.log("While loop count: " + i);
i++;
}
Use this when you don’t know how many times you'll loop.
✅ do...while Loop
Runs the block at least once, and then repeats while the condition is true.
let i = 1;
do {
console.log("Do...While count: " + i);
i++;
} while (i <= 5);
Useful when the loop must run at least once, no matter the condition.
✅ break
Stops the loop entirely.
for (let i = 1; i <= 10; i++) {
if (i === 5) {
break;
}
console.log(i); // prints 1 to 4
}
✅ continue
Skips the current iteration and moves to the next.
for (let i = 1; i <= 5; i++) {
if (i === 3) {
continue;
}
console.log(i); // prints 1, 2, 4, 5
}
5. Functions in JavaScript
🟢 1. Function Declarations vs Expressions
✅ Function Declaration (Named Function)
function greet(name) {
return `Hello, ${name}!`;
}
🟡 2. Parameters vs Arguments
• Parameters: placeholders defined in the function.
• Arguments: actual values passed when calling the function.
function add(x, y) { // x, y = parameters
return x + y;
}
console.log(square(4)); // 16
Arrow functions do not have their own this context. They're best for short functions or
callbacks.
🟠 5. Default Parameters
Set default values for function parameters.
function welcome(name = "Guest") {
console.log(`Welcome, ${name}!`);
}
welcome(); // Welcome, Guest!
welcome("Charlie"); // Welcome, Charlie!
🔴 6. Rest Parameters (...)
Allows a function to accept an infinite number of arguments as an array.
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
You can mix with regular parameters:
function log(first, ...rest) {
console.log(first); // First argument
console.log(rest); // Remaining in array
}
🟤 7. Spread Syntax (...)
Used to unpack values from arrays or objects.
✅ Example with Arrays:
const nums = [1, 2, 3];
const moreNums = [...nums, 4, 5];
console.log(moreNums); // [1, 2, 3, 4, 5]
Example with Objects:
const user = { name: "Tom", age: 25 };
const updatedUser = { ...user, age: 30 };
console.log(updatedUser); // { name: 'Tom', age: 30 }
6. Arrays in JavaScript
An array is an ordered collection of values (elements). These can be strings, numbers, objects,
or even other arrays.
🟢 1. Creating Arrays
✅ Using square brackets (most common):
let fruits = ["apple", "banana", "cherry"];
Using new Array() (less common):
let numbers = new Array(1, 2, 3, 4);
Empty array:
let empty = [];
🟡 2. Accessing and Modifying Elements
• Arrays are zero-indexed (index starts at 0)
• Use [index] to access or modify elements
let colors = ["red", "green", "blue"];
console.log(colors[0]); // "red"
colors[1] = "yellow"; // modifying
console.log(colors); // ["red", "yellow", "blue"]
// Remove items
cart.pop();
cart.shift();
// Insert at position
cart.splice(1, 0, "grape");
// Copy portion
let selected = cart.slice(0, 2);
// Filter by condition
let longNames = cart.filter(item => item.length > 5);
console.log(cart);
console.log(selected);
console.log(upperCase);
console.log(longNames);
console.log("Total characters:", totalChars);
7. Objects in JavaScript
Objects are collections of key-value pairs used to store structured data. They are the building blocks for most
things in JavaScript—from user data to DOM elements and APIs.
🔵 3. Object Methods
Functions that belong to an object are called methods.
const calculator = {
num1: 10,
num2: 5,
add: function() {
return this.num1 + this.num2;
}
};
console.log(calculator.add()); // 15
🟣 4. this Keyword
In object methods, this refers to the object itself.
const user = {
name: "Diana",
greet: function() {
console.log(`Hello, my name is ${this.name}`);
}
};
user.greet(); // Hello, my name is Diana
this becomes tricky in arrow functions, which do not have their own this.
const obj = {
name: "Eve",
arrowGreet: () => {
console.log(`Hi, I'm ${this.name}`); // undefined or wrong!
}
};
obj.arrowGreet(); // Hi, I'm undefined
🟠 5. Nested Objects
An object can have other objects inside it.
const userProfile = {
name: "Frank",
contact: {
email: "[email protected]",
phone: "123-456-7890"
},
skills: ["JS", "HTML", "CSS"]
};
console.log(userProfile.contact.email); // [email protected]
console.log(userProfile.skills[1]); // HTML
You can even nest methods:
const app = {
user: {
name: "Grace",
greet: function() {
console.log(`Hello from ${this.name}`);
}
}
};
app.user.greet(); // Hello from Grace
Real-World Example Using All Concepts
const library = {
name: "City Library",
books: [
{ title: "1984", author: "George Orwell" },
{ title: "The Alchemist", author: "Paulo Coelho" }
],
totalBooks: function() {
return this.books.length;
},
addBook: function(title, author) {
this.books.push({ title, author });
}
};
Example:
<button onclick="alert('Button clicked!')">Click Me</button>
This is called inline event handling (not preferred for larger apps).
<script>
const btn = document.getElementById("myBtn");
btn.addEventListener("click", function() {
alert("Button clicked using addEventListener!");
});
</script>
🔵 3. Event Object
Every event handler receives an event object that contains useful information.
btn.addEventListener("click", function(event) {
console.log("Event type:", event.type); // "click"
console.log("Target element:", event.target);
});
<script>
document.getElementById("outer").addEventListener("click", () => {
console.log("Outer DIV clicked");
});
document.getElementById("inner").addEventListener("click", () => {
console.log("Button clicked");
});
</script>
Clicking the button will trigger:
Button clicked
Outer DIV clicked
✅ Event Capturing:
Use { capture: true } to listen during the capture phase.
document.getElementById("outer").addEventListener("click", () => {
console.log("Captured outer");
}, true);
Order of execution depends on bubbling vs capturing phase.
<script>
const form = document.getElementById("loginForm");
form.addEventListener("submit", function(event) {
event.preventDefault(); // prevent page reload
const username = document.getElementById("username").value;
alert("Welcome, " + username + "!");
});
</script>
<script>
const input = document.getElementById("inputBox");
input.addEventListener("change", () => {
console.log("Input changed!");
});
🟢 1. Selecting Elements
✅ getElementById() – selects by ID
const title = document.getElementById("mainTitle");
getElementsByClassName() – returns HTMLCollection (like an array)
const items = document.getElementsByClassName("list-item");
getElementsByTagName() – returns all elements of a given tag
const paragraphs = document.getElementsByTagName("p");
querySelector() – returns the first match
const firstItem = document.querySelector(".list-item");
querySelectorAll() – returns NodeList of all matches
const allItems = document.querySelectorAll(".list-item");
// First/last child
console.log(list.firstElementChild.textContent);
console.log(list.lastElementChild.textContent);
// Parent element
console.log(list.parentElement);
// Next/previous sibling
console.log(list.nextElementSibling);
console.log(list.previousElementSibling);
<script>
const btn = document.getElementById("addBtn");
const list = document.getElementById("myList");
btn.addEventListener("click", function () {
const newItem = document.createElement("li");
newItem.textContent = "New Task";
newItem.classList.add("list-item");
list.appendChild(newItem);
});
</script>
Task Method
Select by ID getElementById("id")
Select by class/tag getElementsByClassName() / getElementsByTagName()
Modern selection querySelector(), querySelectorAll()
Change content .textContent, .innerHTML
Change attributes .setAttribute(), .getAttribute()
Create/remove elements createElement(), appendChild(), .remove()
Style elements .style, .classList.add()
Traverse DOM .parentElement, .children, .nextElementSibling
JavaScript can interact with and manipulate the DOM to make web pages dynamic.
🟢 1. Selecting Elements
✅ getElementById(id)
<h1 id="title">Hello</h1>
<script>
const title = document.getElementById("title");
console.log(title.textContent); // "Hello"
</script>
✅ querySelector(selector)
<p class="text">First</p>
<p class="text">Second</p>
<script>
const firstText = document.querySelector(".text");
console.log(firstText.textContent); // "First"
</script>
✅ querySelectorAll(selector)
✅ Changing text:
✅ Creating an element:
Removing an element:
document.body.removeChild(newPara); // or newPara.remove();
✅ Inline styles:
title.style.color = "red";
title.style.backgroundColor = "yellow";
Adding/Removing/Toggling classes:
<style>
.highlight { background-color: lightblue; }
</style>
<script>
title.classList.add("highlight");
title.classList.remove("highlight");
title.classList.toggle("highlight");
</script>
<ul id="myList">
<li>Item 1</li>
<li id="secondItem">Item 2</li>
<li>Item 3</li>
</ul>
// Parent element
console.log(secondItem.parentElement);
// Previous sibling
console.log(secondItem.previousElementSibling.textContent); // "Item 1"
// Next sibling
console.log(secondItem.nextElementSibling.textContent); // "Item 3"
<script>
const taskInput = document.getElementById("taskInput");
const addTask = document.getElementById("addTask");
const taskList = document.getElementById("taskList");
addTask.addEventListener("click", function () {
const taskText = taskInput.value;
if (taskText !== "") {
const li = document.createElement("li");
li.textContent = taskText;
taskList.appendChild(li);
taskInput.value = "";
}
});
</script>
Summary Table
JavaScript offers a structured way to handle these using try, catch, finally, and throw.
🔹 Syntax:
try {
// Code that may throw an error
} catch (error) {
// Code to run if there’s an error
} finally {
// (Optional) Code that always runs
}
Example:
try {
let user = JSON.parse('{"name": "Alice"}'); // valid JSON
console.log(user.name); // Alice
} catch (error) {
console.error("Error parsing JSON:", error.message);
} finally {
console.log("Parsing attempt finished.");
}
try {
let user = JSON.parse('{"name": "Bob"'); // missing closing brace
} catch (err) {
console.log("Caught an error:", err.message); // Unexpected end of JSON input
}
🟡 3. throw Statement
You can manually throw errors using throw.
✅ Example:
function divide(a, b) {
if (b === 0) {
throw new Error("Cannot divide by zero!");
}
return a / b;
}
try {
console.log(divide(10, 0));
} catch (e) {
console.error("Math error:", e.message); // Cannot divide by zero!
}
function checkUsername(username) {
if (username.length < 5) {
throw new ValidationError("Username must be at least 5 characters.");
}
return "Username is valid!";
}
try {
console.log(checkUsername("abc")); // too short
} catch (e) {
if (e instanceof ValidationError) {
console.error("Validation failed:", e.message);
} else {
console.error("Unknown error:", e);
}
}
✅ Key Takeaway
• try...catch works only for synchronous code.
• If you’re using setTimeout, setInterval, Promises, or async/await, you must put the try...catch inside the
async callback.
setTimeout(() => {
try {
throw new Error("Async error");
} catch (e) {
console.log("Caught async error:", e.message);
}
}, 1000);
let
Best practice: Use const by default; use let only when reassignment is needed.
Multi-line strings:
const poem = `
Roses are red,
Violets are blue,
JavaScript is awesome,
And so are you.
`;
✅ Array Destructuring:
Object Destructuring:
// Regular function
function greet(name) {
return `Hello, ${name}`;
}
// Arrow version
const greet = (name) => `Hello, ${name}`;
✅ No this binding:
Arrow functions don't create their own this, useful in callbacks or methods.
const person = {
name: "Alice",
greet: function () {
setTimeout(() => {
const obj1 = { a: 1 };
const obj2 = { ...obj1, b: 2 };
console.log(obj2); // { a: 1, b: 2 }
function sum(...numbers) {
return numbers.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum(1, 2, 3)); // 6
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hi, I'm ${this.name}`);
}
}
const p1 = new Person("Alice", 25);
Inheritance:
}
}
console.log(s1.name); // Bob
In math.js:
return a + b;
}
In app.js:
This works in environments that support modules (e.g., with bundlers like Webpack, or in browsers using
<script type="module">).
🔹 7. Enhanced Object Literals
Shorthand methods:
const person = {
greet() {
console.log("Hello!");
}
};
[key]: "hard"
};
console.log(game.level); // hard
🔹 1. Closures
📌 Definition:
A closure is created when a function remembers the variables from its lexical scope, even after the outer
function has finished executing.
✅ Example:
function outer() {
let count = 0;
return function inner() {
count++;
console.log(`Count: ${count}`);
};
}
🔍 Explanation:
• The inner function retains access to count even though the outer has finished running.
• This is a closure — it closes over the count variable.
• Data encapsulation
• Private variables
• Event handlers and timers
🔹 2. Callback Functions
📌 Definition:
✅ Example:
}
greet("Alice", sayGoodbye);
🔍 Explanation:
🔹 3. Recursion
📌 Definition:
✅ Example: Factorial
function factorial(n) {
if (n === 0) return 1; // base case
return n * factorial(n - 1); // recursive call
}
console.log(factorial(5)); // 120
🔍 Use cases:
• Tree structures
• File systems
• Backtracking algorithms (e.g., maze solver)
📌 Definition:
function greet(msg) {
return function(name) {
console.log(`${msg}, ${name}`);
};
}
const sayHello = greet("Hello");
sayHello("Alice"); // Hello, Alice
📌 Definition:
(function () {
console.log("IIFE executed");
})();
✅ Use case:
Used to create private scopes and avoid polluting the global namespace.
🧠 Summary Table
Concept Description Example Use Case
Closures Functions remembering their outer scope Counters, private data
Callback Passing a function to another function Event handling, async code
Tree traversal, factorial,
Recursion Function calling itself
backtracking
Higher-order Functions that accept or return other functions map(), filter(), function factories
IIFE Function that runs immediately Encapsulation, initial setup
🔧 Bonus Tip:
All these concepts work great together.
count++;
console.log(`Counter: ${count}`);
};
})();
counter(); // Counter: 1
counter(); // Counter: 2
✅ setTimeout()
setTimeout(() => {
console.log("Executed after 2 seconds");
}, 2000);
✅ setInterval()
let count = 0;
const timer = setInterval(() => {
✅ Example:
function fetchData(callback) {
setTimeout(() => {
const data = "User data";
callback(data);
}, 1000);
}
fetchData(function(result) {
console.log("Received:", result);
});
⚠️ Callback Hell:
doTask1(() => {
doTask2(() => {
doTask3(() => {
// hard to read!
});
});
});
🔹 3. Promises
A Promise represents a value that may be available now, later, or never.
✅ Syntax:
// or reject("Error!");
}, 1000);
});
myPromise
.then(result => console.log(result)) // Success!
.catch(error => console.log(error)); // if rejected
🧠 States of a Promise:
🔹 4. async / await
✅ async:
✅ await:
✅ Example:
fetchUser();
Summary Table
📦 API Used:
https://randomuser.me/api/
Returns a random user with name, picture, and email.
🧱 Project Structure
index.html
script.js
style.css
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Random User Generator</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>Random User Generator</h1>
<div id="user-card">
<p>Click the button to load a user</p>
</div>
<button id="load-btn">Get Random User</button>
</div>
<script src="script.js"></script>
</body>
</html>
img {
border-radius: 50%;
margin-top: 10px;
}
script.js
const userCard = document.getElementById("user-card");
const loadBtn = document.getElementById("load-btn");
loadBtn.addEventListener("click", fetchUser);
try {
const response = await fetch("https://randomuser.me/api/");
if (!response.ok) throw new Error("Network response was not ok");
const html = `
<img src="${user.picture.large}" alt="User Image" />
<h2>${user.name.title} ${user.name.first} ${user.name.last}</h2>
<p>Email: ${user.email}</p>
<p>Location: ${user.location.city}, ${user.location.country}</p>
`;
userCard.innerHTML = html;
} catch (error) {
userCard.innerHTML = `<p>Error: ${error.message}</p>`;
}
}
🧪 How It Works:
🔹 What is JSON?
✅ Example of JSON:
{
"name": "Alice",
"age": 25,
"isStudent": false,
"skills": ["HTML", "CSS", "JavaScript"]
}
• A string ("Alice")
• A number (25)
• A boolean (false)
• An array (["HTML", "CSS", "JavaScript"])
🔸 1. JSON.stringify()
const user = {
name: "Bob",
age: 30,
skills: ["JS", "React"]
};
Output:
{"name":"Bob","age":30,"skills":["JS","React"]}
🔸 2. JSON.parse()
Useful when:
getUserData();
try {
const response = await fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data) // Convert JS object to JSON
});
sendData();
JSON and Local Storage
const user = { name: "Alice", age: 25 };
Summary
Method Purpose
JSON.stringify() Convert JS object → JSON string
JSON.parse() Convert JSON string → JS object
fetch().json() Parse response body as JSON
body: JSON.stringify() Send JSON data in POST requests
🔹 1. Constructor Functions
Before ES6, constructor functions were used to create objects.
✅ Example:
The new keyword creates a new object and sets this to point to that new object
🔹 2. Prototypes and Prototype Chain
Every JavaScript object has a prototype, which is another object from which it inherits methods and properties.
function Animal(name) {
this.name = name;
}
🧠 Prototype Chain
If a property/method is not found on the object, JavaScript looks up the prototype chain.
✅ Basic class:
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hi, I'm ${this.name}, ${this.age} years old.`);
}
}
✅ Example:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound.`);
}
}
speak() {
console.log(`${this.name} barks!`);
}
}
🔹 5. Encapsulation
Encapsulation means hiding the internal state of an object and only exposing what is necessary. In modern JS,
we use # to make private fields (introduced in ES2022).
✅ Example:
class BankAccount {
#balance = 0;
deposit(amount) {
if (amount > 0) this.#balance += amount;
}
getBalance() {
return this.#balance;
}
}
🔹 6. Abstraction
Abstraction means exposing only essential features and hiding the complexity.
In JS, you simulate abstraction using methods and hiding internal details (with closures or private fields).
✅ Example:
class Car {
start() {
this.#checkEngine();
console.log("Car started");
}
#checkEngine() {
console.log("Engine check complete");
}
}
Summary
Concept Description
Constructor Function Old way to create objects
Prototype Object shared among instances
Class Syntax Cleaner, modern syntax for OOP
Inheritance extends + super() for subclassing
Encapsulation Hiding data using private fields/methods
Abstraction Hide internal complexity, show only essentials
✅ 16. JavaScript Modules
JavaScript Modules allow you to break your code into separate files and reuse them. This improves
organization, readability, and dependency management in both front-end and back-end applications.
✅ Exporting code
// Named export
export function add(a, b) {
return a + b;
}
✅ Importing code
console.log(add(2, 3)); // 5
console.log(subtract(5, 2)); // 3
console.log(PI); // 3.14159
✅ Notes:
In HTML:
// CommonJS syntax
function add(a, b) {
return a + b;
}
const PI = 3.14159;
module.exports = { add, PI };
console.log(add(1, 2)); // 3
console.log(PI); // 3.14159
🔸 3. Module Bundlers
Modern web apps usually have many module files, and browsers don’t natively support things like JSX,
TypeScript, or SCSS. So we use bundlers.
🧰 Popular Bundlers:
// math.js
export const double = x => x * 2;
// index.js
import { double } from './math.js';
console.log(double(5)); // 10
🔹 1. Pure Functions
✅ Definition:
A pure function:
🧠 Example:
// Pure
function square(x) {
return x * x;
}
🔹 2. Immutability
✅ Definition:
🧠 Example:
// Bad (mutation)
numbers.push(4);
// Good (immutable)
const newNumbers = [...numbers, 4]; // [1, 2, 3, 4]
// Object example
const person = { name: "Alice" };
const updatedPerson = { ...person, age: 30 };
🔹 3. Currying
✅ Definition:
Currying is transforming a function with multiple arguments into a sequence of functions, each taking one
argument.
🧠 Example:
function multiply(a, b) {
return a * b;
}
// Curried version
function curriedMultiply(a) {
return function(b) {
return a * b;
};
}
🔹 4. Function Composition
✅ Definition:
console.log(composed(4)); // (4 + 2) * 3 = 18
✅ map()
✅ filter()
✅ reduce()
// { apple: 2, banana: 1 }
Summary Table
Concept Description
Pure Function No side effects, same input → same output
Immutability Data is not mutated, but copied and changed
Currying Function split into single-argument functions
Composition Combine multiple functions into one
map() Transforms array elements
filter() Filters elements based on a condition
reduce() Reduces array to a single value
• Call Stack
• Web APIs
• Task Queue & Microtask Queue
• Event Loop
Understanding these will help you debug, write performant code, and avoid weird async bugs.
🔷 1. Call Stack
The Call Stack is where JavaScript keeps track of function execution.
🧠 How it works:
✅ Example:
function greet() {
console.log("Hello");
}
function sayHi() {
greet();
}
sayHi();
Call Stack:
[ sayHi ]
[ greet ]
[ console.log ]
• setTimeout
• fetch
• DOM Events
• Geolocation are not part of JavaScript — they’re provided by the browser (or Node.js).
✅ Example:
console.log("Start");
setTimeout(() => {
console.log("Inside timeout");
}, 1000);
console.log("End");
Output:
Start
End
Inside timeout
✅ Queues:
Example:
console.log("1");
setTimeout(() => console.log("2"), 0);
Output:
1
4
3 // Microtask
2 // Macrotask
Even though setTimeout(..., 0) seems instant, it’s delayed until the Call Stack is empty and microtasks are
cleared.
🔁 How it works:
console.log("Start");
fetch("https://jsonplaceholder.typicode.com/posts/1")
.then(res => res.json())
.then(data => console.log("Data received:", data));
console.log("End");
Output:
Start
End
Why?
}
getData();
console.log("After fetch call");
Output:
await pauses inside getData(), but not the entire program. console.log("After fetch call") still runs
immediately.
Summary
Concept Description
Call Stack Tracks function calls (LIFO)
Web APIs Provided by browser (timers, fetch, etc.)
Task Queue For async tasks like setTimeout
Microtask Queue For promises, runs before macrotasks
Event Loop Manages the execution order
✅ What it does:
• Uses setTimeout
• Uses Promise.resolve().then(...)
• Uses fetch(...)
• Logs each phase clearly
💻 Full Code (you can run this in the browser)
<!DOCTYPE html>
<html>
<head>
<script>
document.getElementById("start").addEventListener("click", () => {
setTimeout(() => {
}, 0);
Promise.resolve().then(() => {
});
fetch("https://jsonplaceholder.typicode.com/todos/1")
.then(response => {
return response.json();
})
.then(data => {
console.log(" fetch data:", data);
})
});
</script>
</body>
</html>
Script Start
Script End
Promise.then() (Microtask)
✅ What is it?
Garbage Collection is the process of automatically freeing memory that's no longer needed.
✅ How it works:
JS uses Reachability to determine whether a value is still usable. If not, it’s removed from memory.
Example:
let user = {
name: "Alice"
};
🔹 2. Memory Leaks
A memory leak happens when memory that’s no longer needed is not released.
🧠 Common Causes:
document.body.removeChild(element);
// Still in memory because `element` is referenced!
Fix:
element = null;
return function () {
Fix:
const id = setInterval(...);
Example:
fn(...args);
}
};
}
🕐 Debouncing
Example:
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
window.addEventListener("resize", debounce(() => {
// Bad
for (...) {
document.getElementById("item").innerHTML = i;
Better:
Summary
Concept Description
Garbage Collection Automatically frees memory of unreachable data
Memory Leaks When unused memory is unintentionally retained
Throttling Limits execution to once every N ms
Debouncing Delays execution until inactivity
Optimization Includes DOM efficiency, memory, lazy loading, and animations