0% found this document useful (0 votes)
15 views81 pages

Java Script

JavaScript (JS) is a high-level, interpreted programming language that is used to make web pages.

Uploaded by

yeah.9121921
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views81 pages

Java Script

JavaScript (JS) is a high-level, interpreted programming language that is used to make web pages.

Uploaded by

yeah.9121921
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 81

JavaScript

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)

2. Variables and Data Types


• var, let, const
• Primitive types: string, number, boolean, null, undefined, symbol, bigint
• Dynamic typing

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

8. Events and Event Handling


• DOM Events: click, submit, change, etc.
• Event listeners: addEventListener()
• Event bubbling and capturing
• Preventing default behavior
9. DOM Manipulation
• Selecting elements: getElementById, querySelector, etc.
• Modifying content and attributes
• Creating and removing elements
• Styling via JS
• Traversing the DOM

10. Error Handling


• try, catch, finally
• throw statements
• Custom errors

11. ES6+ Features


• let and const
• Template literals
• Destructuring
• Arrow functions
• Spread and rest operators
• Classes and modules
• Enhanced object literals
12. Functions: Advanced Concepts
• Closures
• Callback functions
• Recursion
• Higher-order functions
• IIFE (Immediately Invoked Function Expressions)

13. Asynchronous JavaScript


• setTimeout(), setInterval()
• Callbacks
• Promises
• async / await
• Error handling in async code

14. Working with JSON


• JSON.stringify(), JSON.parse()
• Fetching and sending JSON data via APIs

15. Object-Oriented Programming (OOP)


• Constructor functions
• Prototypes and prototype chain
• class syntax
• Inheritance
• Encapsulation and abstraction

16. JavaScript Modules


• ES6 Modules: import and export
• CommonJS vs ESM
• Module bundlers (Webpack, Parcel)

17. Functional Programming Concepts


• Pure functions
• Immutability
• Currying
• Composition
• map(), reduce(), filter() in depth
18. The Event Loop and Concurrency Model
• Call stack
• Web APIs
• Task queue and microtasks
• Event loop visualization

19. Memory Management and Performance


• Garbage collection
• Memory leaks
• Throttling and debouncing
• Performance optimization tips

20. Error and Debugging Tools


• DevTools (Console, Network, Performance)
• Breakpoints and Watch expressions
• Source maps

21. Advanced Data Structures


• Sets and Maps
• WeakSet and WeakMap
• Typed Arrays
• Linked lists, stacks, and queues (implemented manually)

22. Design Patterns


• Singleton, Module, Factory, Observer, Strategy, etc.
• Creational, Structural, and Behavioral patterns

23. Advanced Asynchronous Patterns


• Async Iterators and Generators
• Web Workers
• Service Workers
• Streams API
24. Metaprogramming
• Proxy and Reflect
• Symbols
• Dynamic property access

25. Security in JavaScript


• Cross-site scripting (XSS)
• Cross-site request forgery (CSRF)
• Content Security Policy (CSP)
• Input sanitization

26. Testing JavaScript


• Unit testing (Jest, Mocha)
• Integration and end-to-end testing
• Test-driven development (TDD)
• Mocking and test coverage

🟢 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.

🟡 2. History and Evolution of JavaScript


Year Milestone
Created by Brendan Eich at Netscape. Initially called Mocha, then renamed to LiveScript, and
1995
finally JavaScript.
1996 Microsoft released JScript, its own implementation for Internet Explorer.
1997 JavaScript was standardized by ECMA International as ECMAScript (ES).
2009 Node.js was created to run JavaScript on servers.
ES6 / ECMAScript 2015 released, bringing major updates (classes, arrow functions, promises,
2015
let/const, etc.).
JavaScript continues to evolve with yearly updates like optional chaining (?.), nullish coalescing
2023+
(??), top-level await, etc.

🔵 3. How JS Runs in the Browser (JS Engine)


Every modern browser has a JavaScript engine that interprets and runs JavaScript code.
Popular JS Engines:
• Chrome → V8
• Firefox → SpiderMonkey
• Safari → JavaScriptCore
• Edge → Chakra (was), now also uses V8
How it works:
1. HTML is parsed by the browser.
2. When a <script> tag is found, the JavaScript engine runs the code.
3. JS can access and manipulate the DOM (Document Object Model).
4. It uses an event loop to handle asynchronous operations like user input or API responses.
Example:
<p id="demo">Old Text</p>
<script>
document.getElementById("demo").innerText = "New Text from JS!";
</script>

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>

<!-- Internal JS for one function -->


<script>
function showAlert() {
alert("Thanks for visiting my profile!");
}
</script>

<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>

<!-- Inline JS to call an alert -->


<button onclick="showAlert()">Say Hello</button>

<!-- External JS handles these -->


<button onclick="toggleInfo()">Toggle Info</button>
<button onclick="changeName()">Change Name</button>
</div>

<!-- External script -->


<script src="script.js"></script>
</body>
</html>

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.

const user = { name: "Alice" };


user.name = "Bob"; // Allowed
// user = {}; Not allowed

🟡 2. Primitive Data Types


JavaScript has 7 primitive data types. These are immutable and hold a single value.
✅ 1. String
Represents text. Enclosed in quotes: ' ', " ", or ` `.
let greeting = "Hello";
let name = 'Alice';
let full = `Hi, my name is ${name}`; // Template literals

✅ 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).

Note: typeof null returns "object" — it's a historical bug in JavaScript.

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.

🧮 Mini Project: JavaScript Calculator


🎯 Features:
• Perform basic operations: add, subtract, multiply, divide
• Show comparison result (greater/less/equal)
• Show result using ternary operator
• Validate inputs (non-empty, numbers)
• Clear result button
Project Structure:
calculator/

├── index.html
├── style.css
├── script.js

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 = '';
}

✅ 4. Control Structures in JavaScript


Control structures let you control the flow of execution in your code. You can make decisions,
repeat tasks, and handle different cases dynamically.

🟢 1. if, else, else if


Used for conditional execution based on whether an expression evaluates to true or false.
✅ Syntax:
if (condition) {
// code if true
} else if (anotherCondition) {
// code if another condition is true
} else {
// code if none of the above
}

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.

🚪 4. break and continue

✅ 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}!`;
}

console.log(greet("Alice")); // Hello, Alice!


Hoisted – can be called before the function is defined.

Function Expression (Anonymous or Named)


const greet = function(name) {
return `Hello, ${name}!`;
};

console.log(greet("Bob")); // Hello, Bob!


Not hoisted – must be defined before use.

🟡 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;
}

add(2, 3); // 2, 3 = arguments


🔵 3. Return Values
A function can return a value using the return keyword.
function multiply(a, b) {
return a * b;
}

let result = multiply(5, 6);


console.log(result); // 30
Without return, the function returns undefined.
🟣 4. Arrow Functions (ES6+)
A shorter syntax to write functions. Especially handy for simple tasks.
✅ Basic Example:
const greet = (name) => {
return `Hi, ${name}!`;
};
Implicit return (one-liner):
const square = x => x * x;

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"]

🔵 3. Array Methods (Add, Remove, Modify Elements)


✅ push() – Add to end
let nums = [1, 2];
nums.push(3); // [1, 2, 3]
pop() – Remove from end
nums.pop(); // [1, 2]
shift() – Remove from start
nums.shift(); // [2]
unshift() – Add to start
nums.unshift(0); // [0, 2]
✅ splice(start, deleteCount, ...items)
Insert/remove/replace elements at any position.
let arr = ["a", "b", "d"];
arr.splice(2, 0, "c"); // insert "c" at index 2
console.log(arr); // ["a", "b", "c", "d"]

arr.splice(1, 2); // remove 2 elements from index 1


console.log(arr); // ["a", "d"]
✅ slice(start, end)
Returns a copy of a portion of the array (non-destructive).
let animals = ["cat", "dog", "bird", "fish"];
let pets = animals.slice(1, 3);
console.log(pets); // ["dog", "bird"]

🟣 4. Iterating Over Arrays


✅ for loop
let cities = ["NY", "London", "Tokyo"];
for (let i = 0; i < cities.length; i++) {
console.log(cities[i]);
}
forEach() – execute a function for each element
cities.forEach(function(city) {
console.log("City:", city);
});
map() – transforms array elements and returns a new array
let numbers = [1, 2, 3];
let squared = numbers.map(num => num * num);
console.log(squared); // [1, 4, 9]
filter() – returns a new array of elements that match condition
let nums = [1, 2, 3, 4, 5];
let even = nums.filter(n => n % 2 === 0);
console.log(even); // [2, 4]
reduce() – reduces the array to a single value
let nums = [1, 2, 3, 4];
let sum = nums.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 10
let cart = ["apple", "banana"];

Practical Example Using Everything


// Add items
cart.push("orange");
cart.unshift("mango");

// Remove items
cart.pop();
cart.shift();

// Insert at position
cart.splice(1, 0, "grape");

// Copy portion
let selected = cart.slice(0, 2);

// Print using forEach


cart.forEach(item => console.log("Item:", item));

// Transform using map


let upperCase = cart.map(item => item.toUpperCase());

// Filter by condition
let longNames = cart.filter(item => item.length > 5);

// Reduce to count total characters


let totalChars = cart.reduce((sum, item) => sum + item.length, 0);

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.

🟢 1. Object Literals and Constructors


✅ Object Literal Syntax
The most common way to create an object.
const person = {
name: "Alice",
age: 30,
isStudent: false
};
✅ Object Constructor Syntax
Using the Object constructor or custom constructors:
const person = new Object();
person.name = "Bob";
person.age = 25;
Or define your own constructor:
function Person(name, age) {
this.name = name;
this.age = age;
}

const user = new Person("Charlie", 28);


console.log(user); // { name: "Charlie", age: 28 }

🟡 2. Accessing and Modifying Properties


✅ Dot Notation
console.log(person.name); // "Alice"
person.age = 31;
Bracket Notation (useful for dynamic keys or special characters)
console.log(person["name"]); // "Alice"
let key = "age";
console.log(person[key]); // 31

🔵 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 });
}
};

console.log(library.name); // City Library


console.log(library.totalBooks()); // 2

library.addBook("Dune", "Frank Herbert");


console.log(library.totalBooks()); // 3
console.log(library.books[2].title); // Dune

8. Events and Event Handling in JavaScript


🔹 What are Events?
Events are actions or occurrences that happen in the browser (e.g., clicking a button, submitting a form,
changing input text) which you can respond to using JavaScript.
1. Common DOM Events
Event Type Description
click When an element is clicked
submit When a form is submitted
change When the value of an input changes
keydown When a key is pressed down
When the mouse moves over an
mouseover
element

Example:
<button onclick="alert('Button clicked!')">Click Me</button>
This is called inline event handling (not preferred for larger apps).

🟡 2. Event Listeners: addEventListener()


Preferred method to handle events in modern JavaScript.
<button id="myBtn">Click Me</button>

<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);
});

🟣 4. Event Bubbling and Capturing


✅ Event Bubbling (default):
The event starts at the target element and bubbles up through its parents.
<div id="outer">
<button id="inner">Click Me</button>
</div>

<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.

🔴 5. Preventing Default Behavior


Some elements have default behaviors (e.g., form submits, links navigate). You can stop this with:
form.addEventListener("submit", function(e) {
e.preventDefault(); // Stops the form from submitting
console.log("Form submission prevented!");
});

Real World Example


<form id="loginForm">
<input type="text" id="username" placeholder="Username" />
<button type="submit">Login</button>
</form>

<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>

Another Example with Change and Key Events


<input type="text" id="inputBox" placeholder="Type something..." />

<script>
const input = document.getElementById("inputBox");

input.addEventListener("change", () => {
console.log("Input changed!");
});

input.addEventListener("keydown", (e) => {


console.log("Key pressed:", e.key);
});
</script>

9. DOM Manipulation in JavaScript


The DOM (Document Object Model) is a tree-like structure representing your HTML page, which JavaScript
can interact with to read, change, add, or remove content.

🟢 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");

🟡 2. Modifying Content and Attributes


✅ Changing text:
const heading = document.getElementById("mainTitle");
heading.textContent = "Updated Title";
Changing inner HTML:
heading.innerHTML = "<em>Updated</em> Title";
Changing attributes:
const link = document.querySelector("a");
link.href = "https://newsite.com";
link.setAttribute("target", "_blank");
Getting attributes:
console.log(link.getAttribute("href")); // https://newsite.com

🔵 3. Creating and Removing Elements


✅ Creating elements:
const newItem = document.createElement("li");
newItem.textContent = "New List Item";
Adding to the DOM:
const list = document.getElementById("myList");
list.appendChild(newItem);
Removing elements:
list.removeChild(newItem);
Or modern approach:
newItem.remove();

🟣 4. Styling via JavaScript


✅ Inline styles:
heading.style.color = "blue";
heading.style.fontSize = "24px";
Toggle classes:
heading.classList.add("highlight");
heading.classList.remove("highlight");
heading.classList.toggle("hidden"); // toggle adds/removes
You can also check:
if (heading.classList.contains("hidden")) {
console.log("It's hidden!");
}

🟠 5. Traversing the DOM


Navigate the DOM tree using parent-child-sibling relationships.
const list = document.getElementById("myList");
// Child elements
console.log(list.children); // HTMLCollection

// 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);

Real World Example <h2 id="mainTitle">To-Do List</h2>


<ul id="myList">
<li class="list-item">Task 1</li>
<li class="list-item">Task 2</li>
</ul>
<button id="addBtn">Add Task</button>

<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

✅ 9. DOM Manipulation in JavaScript


📌 What is the DOM?
DOM (Document Object Model) is a programming interface for HTML and XML documents. It represents
the page so that programs can change the document structure, style, and content.

JavaScript can interact with and manipulate the DOM to make web pages dynamic.

🟢 1. Selecting Elements

✅ getElementById(id)

Selects a single element with the specified ID.

<h1 id="title">Hello</h1>
<script>
const title = document.getElementById("title");
console.log(title.textContent); // "Hello"
</script>

✅ querySelector(selector)

Selects the first element that matches a CSS 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)

Selects all elements that match a CSS selector. Returns a NodeList.


const allText = document.querySelectorAll(".text");
allText.forEach((p) => console.log(p.textContent));

🟡 2. Modifying Content and Attributes

✅ Changing text:

title.textContent = "New Title";


Changing HTML inside an element:
title.innerHTML = "<em>Styled Title</em>";

Changing or getting attributes:


<a id="myLink" href="https://google.com">Google</a>
<script>
const link = document.getElementById("myLink");
link.setAttribute("href", "https://openai.com");
console.log(link.getAttribute("href")); // https://openai.com
</script>

🔵 3. Creating and Removing Elements

✅ Creating an element:

const newPara = document.createElement("p");


newPara.textContent = "I'm new here!";

Appending to the DOM:


document.body.appendChild(newPara);

Removing an element:
document.body.removeChild(newPara); // or newPara.remove();

🟣 4. Styling via JavaScript

✅ 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>

🟠 5. Traversing the DOM


You can navigate between elements in the DOM tree.

<ul id="myList">
<li>Item 1</li>
<li id="secondItem">Item 2</li>
<li>Item 3</li>
</ul>

const secondItem = document.getElementById("secondItem");

// Parent element
console.log(secondItem.parentElement);

// Previous sibling
console.log(secondItem.previousElementSibling.textContent); // "Item 1"

// Next sibling
console.log(secondItem.nextElementSibling.textContent); // "Item 3"

// All children of list


const list = document.getElementById("myList");
console.log(list.children); // HTMLCollection of li items

Full Example: Add Items to List


<h2>Todo List</h2>
<input type="text" id="taskInput" placeholder="Enter task">
<button id="addTask">Add Task</button>
<ul id="taskList"></ul>

<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

Concept Method / Property


Select by ID getElementById("id")
Select with CSS selector querySelector(), querySelectorAll()
Modify content textContent, innerHTML
Modify attributes setAttribute(), getAttribute()
Create/append element createElement(), appendChild()
Remove element remove(), removeChild()
Style with JS element.style.property, classList
Traverse DOM parentElement, children, nextElementSibling

✅ 10. Error Handling in JavaScript – In Depth

📌 Why Error Handling?


Code can break due to:
• Syntax errors (e.g., missing brackets)
• Runtime errors (e.g., accessing undefined variables)
• Logical errors (e.g., incorrect conditions)

JavaScript offers a structured way to handle these using try, catch, finally, and throw.

🟢 1. try, catch, and finally

🔹 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.");
}

finally block always runs, regardless of whether there was an error.

🔴 2. What if there's an actual error?


Example with a faulty JSON:

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!
}

🟣 4. Creating Custom Errors


You can create your own error types by extending the built-in Error class.

✅ Custom Error Class:

class ValidationError extends Error {


constructor(message) {
super(message);
this.name = "ValidationError";
}
}

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);
}
}

Real-World Form Validation Example:


<input type="text" id="ageInput" placeholder="Enter your age">
<button onclick="validateAge()">Submit</button>
<script>
function validateAge() {
const age = document.getElementById("ageInput").value;
try {
if (age === "") {
throw new Error("Age is required.");
}
if (isNaN(age)) {
throw new Error("Age must be a number.");
}
if (age < 18) {
throw new Error("You must be at least 18 years old.");
}
alert("Age is valid!");
} catch (e) {
alert("Error: " + e.message);
} finally {
console.log("Validation complete.");
}
}
</script>

✅ 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);

🧠 Why use try...catch with async/await?


Because if you don't, unhandled Promise rejections can crash your app or go unnoticed.

async function fetchData() {


try {
const response = await fetch("invalid-url");
} catch (err) {
console.log("Caught async error:", err.message);
}
}

✅ 11. ES6+ Features in JavaScript – Explained


with Examples

🔹 1. let and const (Block Scoped Variables)

let

• Used to declare variables that can be reassigned.


• Block scoped (only accessible within {} block).

let name = "Alice";


name = "Bob"; // Allowed
console.log(name); // "Bob"
const

• Used to declare constants (cannot be reassigned).


• Also block scoped.

const age = 30;


// age = 40; Error: Assignment to constant variable

Best practice: Use const by default; use let only when reassignment is needed.

🔹 2. Template Literals (Backticks for String Interpolation)


Syntax:

const name = "Alice";


const greeting = `Hello, ${name}!`;
console.log(greeting); // "Hello, Alice!"

Multi-line strings:
const poem = `
Roses are red,
Violets are blue,
JavaScript is awesome,
And so are you.
`;

🔹 3. Destructuring (Extracting values from arrays/objects)

✅ Array Destructuring:

const numbers = [1, 2, 3];


const [a, b] = numbers;
console.log(a, b); // 1 2

Object Destructuring:

const user = { name: "Alice", age: 25 };


const { name, age } = user;
console.log(name, age); // Alice 25

You can also rename while destructuring:


const { name: username } = user;
console.log(username); // Alice

4. Arrow Functions (Concise Function Syntax)

// 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(() => {

console.log(`Hi, I'm ${this.name}`);


}, 1000);
}
};

person.greet(); // Hi, I'm Alice


🔹 5. Spread and Rest Operators (...)

✅ Spread: Expands arrays or objects

const arr1 = [1, 2];


const arr2 = [...arr1, 3, 4];
console.log(arr2); // [1, 2, 3, 4]

const obj1 = { a: 1 };
const obj2 = { ...obj1, b: 2 };
console.log(obj2); // { a: 1, b: 2 }

Rest: Collects values into an array

function sum(...numbers) {
return numbers.reduce((acc, curr) => acc + curr, 0);

}
console.log(sum(1, 2, 3)); // 6

🔹 6. Classes and Modules

✅ Classes (OOP in JavaScript)

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);

p1.greet(); // Hi, I'm Alice

Inheritance:

class Student extends Person {

constructor(name, age, grade) {


super(name, age);
this.grade = grade;

}
}

const s1 = new Student("Bob", 20, "A");

console.log(s1.name); // Bob

✅ Modules (ES6 import / export)

In math.js:

export function add(a, b) {

return a + b;
}

In app.js:

import { add } from './math.js';


console.log(add(2, 3)); // 5

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 property names:

const name = "Alice", age = 25;


const user = { name, age };
console.log(user); // { name: "Alice", age: 25 }

Shorthand methods:

const person = {
greet() {

console.log("Hello!");
}
};

Computed property names:

const key = "level";


const game = {

[key]: "hard"
};
console.log(game.level); // hard

✅ 12. Functions: Advanced Concepts

🔹 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}`);
};
}

const counter = outer();


counter(); // Count: 1
counter(); // Count: 2

🔍 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.

Closures are useful for:

• Data encapsulation
• Private variables
• Event handlers and timers

🔹 2. Callback Functions

📌 Definition:

A callback function is a function passed as an argument to another function, to be executed later.

✅ Example:

function greet(name, callback) {


console.log(`Hello, ${name}`);
callback();
}
function sayGoodbye() {
console.log("Goodbye!");

}
greet("Alice", sayGoodbye);

🔍 Explanation:

• sayGoodbye is passed to greet() and called later.


• Used heavily in async operations, events, and array methods.

🔹 3. Recursion

📌 Definition:

Recursion is a function that calls itself until it reaches a base case.

✅ 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)

Always include a base case to prevent infinite loops.


🔹 4. Higher-Order Functions

📌 Definition:

A higher-order function is a function that:

• Takes another function as an argument, or


• Returns a function

✅ Example: Using array methods

const numbers = [1, 2, 3, 4];

const doubled = numbers.map(num => num * 2);


console.log(doubled); // [2, 4, 6, 8]

Example: Returning a function

function greet(msg) {
return function(name) {
console.log(`${msg}, ${name}`);

};
}
const sayHello = greet("Hello");
sayHello("Alice"); // Hello, Alice

🔍 Common higher-order functions:

• map(), filter(), reduce(), forEach()


• Event handlers
• Middleware in frameworks (like Express.js)

🔹 5. IIFE (Immediately Invoked Function Expression)

📌 Definition:

An IIFE is a function that executes immediately after being defined.


✅ Syntax:

(function () {
console.log("IIFE executed");
})();

✅ Use case:

Used to create private scopes and avoid polluting the global namespace.

✅ Example with variables:

const result = (function () {


const hidden = "secret";

return `Access granted to ${hidden}`;


})();

console.log(result); // Access granted to secret

🧠 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.

💡 Example using closure + IIFE + higher-order:

const counter = (function () {


let count = 0;
return function () {

count++;
console.log(`Counter: ${count}`);
};

})();

counter(); // Counter: 1
counter(); // Counter: 2

✅ 13. Asynchronous JavaScript – Complete Guide


with Examples
JavaScript is single-threaded, meaning it runs one operation at a time. Asynchronous code allows us to
perform non-blocking operations (like fetching data from an API) while continuing other tasks.

🔹 1. setTimeout() & setInterval()

✅ setTimeout()

Runs a function once after a delay.

setTimeout(() => {
console.log("Executed after 2 seconds");
}, 2000);

✅ setInterval()

Runs a function repeatedly at intervals.

let count = 0;
const timer = setInterval(() => {

console.log("Repeats every second", ++count);


if (count === 5) clearInterval(timer); // stop after 5 times
}, 1000);
🔹 2. Callback Functions
A callback is a function passed as an argument to another function and executed later.

✅ Example:

function fetchData(callback) {
setTimeout(() => {
const data = "User data";

callback(data);
}, 1000);
}

fetchData(function(result) {
console.log("Received:", result);
});

⚠️ Callback Hell:

When callbacks are deeply nested, it becomes hard to manage:

doTask1(() => {
doTask2(() => {
doTask3(() => {

// hard to read!

});
});

});

🔹 3. Promises
A Promise represents a value that may be available now, later, or never.

✅ Syntax:

const myPromise = new Promise((resolve, reject) => {


setTimeout(() => {
resolve("Success!");

// or reject("Error!");
}, 1000);
});

myPromise
.then(result => console.log(result)) // Success!
.catch(error => console.log(error)); // if rejected

🧠 States of a Promise:

• pending – initial state


• fulfilled – completed successfully
• rejected – failed

🔹 4. async / await

✅ async:

Declares a function that returns a Promise.

✅ await:

Waits for the result of a Promise inside an async function.

✅ Example:

async function getData() {


try {
const response = await fetch("https://jsonplaceholder.typicode.com/posts/1");
const data = await response.json();
console.log(data);
} catch (err) {
console.error("Error:", err.message);
}
}
getData();

This is much cleaner than chaining .then() and .catch().

🔹 5. Error Handling in Async Code

✅ try...catch with async/await

async function fetchUser() {


try {
const res = await fetch("invalid-url"); // throws
const user = await res.json();
console.log(user);
} catch (error) {
console.log("Caught async error:", error.message);
}
}

fetchUser();

catch() with Promises


fetch("invalid-url")
.then(res => res.json())
.catch(err => console.error("Caught promise error:", err.message));

Summary Table

Feature Description Example Usage


setTimeout() Run function after delay Delay task
setInterval() Run function repeatedly Timers, counters
Callback Function passed to another function Event handlers, async logic
Promise Handle async result with then/catch Fetching data, reading files
async/await Cleaner way to work with Promises Modern async code, API calls
try...catch Handle errors in async code Prevent crashes

🛠️ Mini Project: Random User Generator


This app will:

• Fetch random user data from an API


• Display the user’s name, picture, and email
• Use async/await and error handling
• Dynamically update the DOM

📦 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>

style.css (Optional Styling)


body {
font-family: Arial, sans-serif;
background: #f0f2f5;
text-align: center;
padding: 40px;
}
.container {
background: white;
padding: 20px;
max-width: 400px;
margin: auto;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}

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);

async function fetchUser() {


userCard.innerHTML = "<p>Loading...</p>";

try {
const response = await fetch("https://randomuser.me/api/");
if (!response.ok) throw new Error("Network response was not ok");

const data = await response.json();


const user = data.results[0];

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:

1. When the button is clicked, fetchUser() is called.


2. fetchUser() uses async/await to call the API and waits for the response.
3. The data is parsed and inserted into the DOM.
4. Errors (like network issues) are caught and shown in the UI.

✅ 14. Working with JSON in JavaScript

🔹 What is JSON?

📌 JSON = JavaScript Object Notation

It is a lightweight format used to store and exchange data.

• Based on JavaScript object syntax


• Language-independent
• Text-based and easily readable
• Used extensively in APIs

✅ Example of JSON:

{
"name": "Alice",
"age": 25,
"isStudent": false,
"skills": ["HTML", "CSS", "JavaScript"]
}

This is a JSON object containing:

• A string ("Alice")
• A number (25)
• A boolean (false)
• An array (["HTML", "CSS", "JavaScript"])

JavaScript Object vs JSON


JavaScript Object JSON
key: value (no quotes needed) "key": "value" (quotes on keys)
Can have methods Cannot have functions
Variables can be anything Only supports specific types

🔸 1. JSON.stringify()

📌 Converts a JavaScript object → JSON string

const user = {
name: "Bob",
age: 30,
skills: ["JS", "React"]
};

const jsonString = JSON.stringify(user);


console.log(jsonString);

Output:
{"name":"Bob","age":30,"skills":["JS","React"]}

You might use this when:

• Sending data in an HTTP request


• Storing in localStorage

🔸 2. JSON.parse()

📌 Converts a JSON string → JavaScript object

const jsonStr = '{"name":"Bob","age":30,"skills":["JS","React"]}';


const userObj = JSON.parse(jsonStr);
console.log(userObj.name); // Bob

Useful when:

• Receiving JSON data from an API


• Reading from localStorage
🔹 Practical Use Case: Fetch JSON from an API

✅ Example: Using fetch() and async/await

async function getUserData() {


try {
const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
const user = await response.json(); // parse the JSON response
console.log(user.name); // Leanne Graham
} catch (error) {
console.error("Error fetching data:", error);
}
}

getUserData();

Sending JSON via API (POST request)


async function sendData() {
const data = {
name: "Charlie",
age: 28
};

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
});

const result = await response.json();


console.log("Server response:", result);
} catch (err) {
console.log("Failed to send data:", err);
}
}

sendData();
JSON and Local Storage
const user = { name: "Alice", age: 25 };

// Save to localStorage as JSON string


localStorage.setItem("user", JSON.stringify(user));
// Read and parse back to object
const storedUser = JSON.parse(localStorage.getItem("user"));
console.log(storedUser.name); // Alice

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

✅ 15. Object-Oriented Programming (OOP) in


JavaScript
JavaScript supports object-oriented programming (OOP) using both prototypes and ES6 class syntax. OOP
helps you structure your code using objects that bundle data and behavior.

🔹 1. Constructor Functions
Before ES6, constructor functions were used to create objects.

✅ Example:

function Person(name, age) {


this.name = name;
this.age = age;
this.sayHello = function () {
console.log(`Hello, I'm ${this.name}`);
};
}

const person1 = new Person("Alice", 25);


person1.sayHello(); // Hello, I'm Alice

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.

✅ Example: Using prototype to share methods

function Animal(name) {
this.name = name;
}

// Shared method added to prototype


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

const dog = new Animal("Dog");


dog.speak(); // Dog makes a noise.

🧠 Prototype Chain

If a property/method is not found on the object, JavaScript looks up the prototype chain.

dog → Animal.prototype → Object.prototype → null

🔹 3. ES6 class Syntax (Modern OOP)


Introduced in ES6 for easier and cleaner syntax (syntactic sugar over prototype-based inheritance).

✅ 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.`);
}
}

const user1 = new Person("Bob", 30);


user1.greet(); // Hi, I'm Bob, 30 years old.
🔹 4. Inheritance
Inheritance allows a class to inherit properties and methods from another class using the extends keyword.

✅ Example:

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

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

class Dog extends Animal {


constructor(name, breed) {
super(name); // calls Animal constructor
this.breed = breed;
}

speak() {
console.log(`${this.name} barks!`);
}
}

const d = new Dog("Max", "Labrador");


d.speak(); // Max 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;
}
}

const acc = new BankAccount();


acc.deposit(100);
console.log(acc.getBalance()); // 100
// acc.#balance → SyntaxError: Private field

🔹 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");
}
}

const myCar = new Car();


myCar.start(); // Engine check complete \n Car started
// myCar.#checkEngine() → Private method

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.

🔹 Why Use Modules?


• Avoid polluting the global scope
• Reuse code easily across files
• Better separation of concerns
• Support for lazy-loading and tree-shaking

🔸 1. ES6 Modules (ESM)


Introduced in ES6 (2015) and now the standard in modern JavaScript.

✅ Exporting code

Create a file math.js:

// Named export
export function add(a, b) {
return a + b;
}

// Another named export


export const PI = 3.14159;

// Default export (only one per file)


export default function subtract(a, b) {
return a - b;
}

✅ Importing code

In another file app.js:


// Import named exports
import { add, PI } from './math.js';

// Import default export


import subtract from './math.js';

console.log(add(2, 3)); // 5
console.log(subtract(5, 2)); // 3
console.log(PI); // 3.14159

✅ Notes:

• Use .js extension when importing


• Only works in ES6 environments or with type="module"
• You must serve files over a server (not directly from the file system)

In HTML:

<script type="module" src="app.js"></script>

🔸 2. CommonJS (Node.js default)


This is the older module system used in Node.js.

✅ Exporting code (math.js)

// CommonJS syntax
function add(a, b) {
return a + b;
}

const PI = 3.14159;

module.exports = { add, PI };

Importing code (app.js)


const { add, PI } = require('./math');

console.log(add(1, 2)); // 3
console.log(PI); // 3.14159

Difference Between CommonJS vs ES6 Modules


Feature CommonJS ES Modules (ESM)
Syntax require(), module.exports import, export
When introduced Earlier (Node.js) ES6 (2015)
Synchronous Yes No (asynchronous)
Runs in browsers No (without bundler) Yes (with type="module")
Default export Yes Yes

🔸 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:

Bundler Use Case


Webpack Most customizable and powerful
Parcel Zero-config, fast
Vite Modern, super fast dev experience
Rollup Great for libraries

✅ Example with Webpack

1. You write ES6 modules:

// math.js
export const double = x => x * 2;

// index.js
import { double } from './math.js';
console.log(double(5)); // 10

Webpack bundles your files into one: bundle.js


<script src="dist/bundle.js"></script>
✅ 17. Functional Programming Concepts in
JavaScript
Functional Programming (FP) encourages writing pure, reusable, and composable functions. It's a great way
to write predictable, testable, and bug-resistant code.

🔹 1. Pure Functions

✅ Definition:

A pure function:

• Has no side effects (does not modify external state)


• Given the same input, always returns the same output

🧠 Example:

// Pure
function square(x) {
return x * x;
}

// Impure (modifies external state)


let counter = 0;
function increment() {
counter++;
}

🔹 2. Immutability

✅ Definition:

Immutability means data is never modified, only copied and changed.

🧠 Example:

const numbers = [1, 2, 3];

// 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;
};
}

const double = curriedMultiply(2);


console.log(double(5)); // 10

Using arrow functions:


const curriedAdd = a => b => a + b;
console.log(curriedAdd(3)(4)); // 7

🔹 4. Function Composition

✅ Definition:

Combining small functions to build more complex ones.


🧠 Example:

const add2 = x => x + 2;


const multiply3 = x => x * 3;

const composed = x => multiply3(add2(x));

console.log(composed(4)); // (4 + 2) * 3 = 18

You can also write a utility for composition:


const compose = (f, g) => x => f(g(x));

const result = compose(multiply3, add2)(4); // 18

🔹 5. map(), filter(), reduce() — In Depth


These are higher-order functions used to manipulate arrays immutably.

✅ map()

Applies a function to each item and returns a new array.

const nums = [1, 2, 3];


const doubled = nums.map(n => n * 2); // [2, 4, 6]

✅ filter()

Filters items based on a condition.

const nums = [1, 2, 3, 4];


const evens = nums.filter(n => n % 2 === 0); // [2, 4]

✅ reduce()

Reduces an array to a single value (e.g., sum, object, or array).


const nums = [1, 2, 3, 4];
const total = nums.reduce((acc, curr) => acc + curr, 0); // 10

More advanced reduce:


const fruits = ['apple', 'banana', 'apple'];

const count = fruits.reduce((acc, fruit) => {


acc[fruit] = (acc[fruit] || 0) + 1;
return acc;
}, {});

// { 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

✅ 18. The Event Loop and Concurrency Model in


JavaScript
JavaScript is single-threaded, meaning it can do one thing at a time. But it handles asynchronous operations
(like setTimeout, API calls) seamlessly using its Concurrency Model with:

• 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:

• When a function is called, it gets pushed on top of the stack.


• When it finishes, it gets popped off.

✅ Example:

function greet() {
console.log("Hello");
}

function sayHi() {
greet();
}
sayHi();

Call Stack:

[ sayHi ]
[ greet ]

[ console.log ]

Once console.log finishes, it pops, then greet, then sayHi.

🔷 2. Web APIs (Provided by the Browser/Runtime)


Functions like:

• 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

🔷 3. Task Queue (Macro Task) & Microtask Queue


Once async code (like setTimeout) completes, the callback doesn't run immediately — it's queued.

✅ Queues:

Type Includes Priority


Task Queue (Macro) setTimeout, setInterval, setImmediate Low
Microtask Queue Promise.then(), queueMicrotask() High

Example:

console.log("1");
setTimeout(() => console.log("2"), 0);

Promise.resolve().then(() => console.log("3"));


console.log("4");

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.

🔷 4. The Event Loop


The Event Loop is what makes JavaScript asynchronous.

🔁 How it works:

1. Check if the Call Stack is empty


2. If yes, process microtasks
3. Then process macrotasks
4. Repeat!

It continuously loops, checking if there’s anything to do.

Real-world example with fetch

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

Data received: {...}

Why?

• fetch() runs in the Web API environment


• .then() callback is scheduled in the Microtask Queue
• console.log("End") runs before .then() is executed
🧪 Bonus: Using async/await
async function getData() {
const res = await fetch("https://jsonplaceholder.typicode.com/posts/1");
const data = await res.json();
console.log(data);

}
getData();
console.log("After fetch call");

Output:

After fetch call


{ userId: ..., id: ..., title: ..., body: ... }

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

🛠️ Mini Event Loop Demo App

✅ 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>

<title>Event Loop Demo</title>


</head>
<body>

<h2>Open your console to see the Event Loop in action</h2>


<button id="start">Start Demo</button>

<script>

document.getElementById("start").addEventListener("click", () => {

console.log(" Script Start");

setTimeout(() => {

console.log(" setTimeout Callback (Macrotask)");

}, 0);

Promise.resolve().then(() => {

console.log(" Promise.then() (Microtask)");

});

fetch("https://jsonplaceholder.typicode.com/todos/1")
.then(response => {

console.log(" fetch.then() (Microtask after fetch completes)");

return response.json();
})
.then(data => {
console.log(" fetch data:", data);

})

.catch(error => console.log(" fetch error:", error));

console.log(" Script End");

});
</script>
</body>

</html>

Sample Output in Console:

Script Start

Script End

Promise.then() (Microtask)

setTimeout Callback (Macrotask)

fetch.then() (Microtask after fetch completes)

fetch data: { userId: 1, id: 1, ... }

✅ 19. Memory Management and Performance in


JavaScript
JavaScript automatically manages memory, but understanding how it works helps avoid memory leaks and
improve performance.
🔹 1. Garbage Collection (GC)

✅ 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"
};

user = null; // The object is now unreachable -> GC will clean it up

🧹 Common Algorithm: Mark and Sweep

1. JS marks all reachable values


2. Unmarked values are removed from memory

You don’t control when GC runs — the engine decides.

🔹 2. Memory Leaks
A memory leak happens when memory that’s no longer needed is not released.

🧠 Common Causes:

a) Unused DOM References

let element = document.getElementById("myDiv");

document.body.removeChild(element);
// Still in memory because `element` is referenced!

Fix:

element = null;

b) Closures Holding References


function leaky() {

let largeData = new Array(1000000).fill("leak");

return function () {

console.log("Still holding largeData");


};
}

const fn = leaky(); // largeData is never released

Fix: Be careful with closures and clean up unused references.

c) Forgotten Timers or Intervals


setInterval(() => {
console.log("Running forever...");
}, 1000);

Fix:

const id = setInterval(...);

clearInterval(id); // when done

🔹 3. Throttling and Debouncing


Used to limit how often a function is executed — super useful for scroll, resize, or key events.
🔁 Throttling

Executes a function at most once every N ms.

Example:

function throttle(fn, delay) {


let lastCall = 0;
return function (...args) {

const now = new Date().getTime();


if (now - lastCall >= delay) {
lastCall = now;

fn(...args);
}
};
}

window.addEventListener("resize", throttle(() => {


console.log("Throttled resize event");
}, 1000));

🕐 Debouncing

Waits until a pause in events before executing.

Example:

function debounce(fn, delay) {


let timer;
return function (...args) {

clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
window.addEventListener("resize", debounce(() => {

console.log("Debounced resize event");


}, 1000));

🔹 4. Performance Optimization Tips

✅ a) Minimize DOM Access

DOM operations are slow:

// Bad
for (...) {
document.getElementById("item").innerHTML = i;

Better:

const item = document.getElementById("item");


for (...) {
item.innerHTML = i;
}

b) Avoid Memory-Heavy Structures


let arr = new Array(1e9); // Large memory consumption

Use lazy loading, pagination, or streams when handling big data.

✅ c) Use Web Workers for Heavy Tasks

Run background tasks without freezing the UI.


✅ d) Minify and Bundle Your Code

Use tools like Webpack, Parcel, or Rollup to reduce size.

✅ e) Use requestAnimationFrame() for Animations

Instead of setInterval or setTimeout, which can cause jank.

✅ f) Monitor with DevTools

Use Chrome DevTools → Performance tab to:

• Track memory usage


• See GC runs
• Spot memory leaks (heap snapshots)

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

You might also like