Chapter 2 Advanced JavaScript (ES6+)
2.1 ES6 Syntax Features (ECMAScript 2015)
ES6 (ECMAScript 2015) introduced many powerful features that make JavaScript code
shorter, cleaner, and easier to understand.
Some of the most important ES6 syntax features are:
1. Arrow Functions and Lexical this
2. Template Literals and String Interpolation
3. Object and Array Destructuring
4. Default Parameters
1. Arrow Functions and Lexical this
Arrow functions are a shorter way of writing JavaScript functions. They were introduced in
ES6 to reduce code length and improve readability.
Unlike regular functions, arrow functions do not have their own this keyword. Instead,
they inherit (lexically bind) the this value from the surrounding scope.
Syntax
const functionName = (parameters) => {
// code
};
Traditional Function
function add(a, b) {
return a + b;
}
[Link](add(5, 3));
Output
8
Arrow Function
const add = (a, b) => {
return a + b;
};
[Link](add(5, 3));
Output
Single Parameter
const square = num => {
return num * num;
};
[Link](square(6));
Output
36
Single Line Arrow Function
When there is only one statement, return is implicit.
const multiply = (a, b) => a * b;
[Link](multiply(4, 5));
Output
20
Lexical this
Regular Function
In a regular function, this refers to the object calling the function.
const person = {
name: "Rahul",
greet: function () {
[Link]([Link]);
}
};
[Link]();
Output
Rahul
Problem with Regular Function
const person = {
name: "Rahul",
greet: function () {
setTimeout(function () {
[Link]([Link]);
}, 1000);
}
};
[Link]();
Output
undefined
The callback has its own this, which is not the person object.
Arrow Function Solves This
const person = {
name: "Rahul",
greet: function () {
setTimeout(() => {
[Link]([Link]);
}, 1000);
}
};
[Link]();
Output
Rahul
Arrow functions inherit this from the surrounding greet() function.
Advantages of Arrow Functions
Less code
Easier to read
Automatically inherits this
Great for callbacks
Makes functional programming easier
2. Template Literals and String Interpolation
Before ES6, strings were created using single (' ') or double (" ") quotes.
ES6 introduced Template Literals, which use backticks ( ).
Template literals support:
Multi-line strings
Variable interpolation
Expression evaluation
Cleaner string formatting
Syntax
`string`
Traditional String Concatenation
let name = "Amit";
let age = 21;
let message = "My name is " + name + " and I am " + age + " years old.";
[Link](message);
Output
My name is Amit and I am 21 years old.
Template Literal
let name = "Amit";
let age = 21;
let message = `My name is ${name} and I am ${age} years old.`;
[Link](message);
Output
My name is Amit and I am 21 years old.
String Interpolation
String interpolation means inserting variables or expressions inside a string using ${}.
let price = 500;
let quantity = 3;
[Link](`Total Price = ${price * quantity}`);
Output
Total Price = 1500
Using Expressions
let a = 10;
let b = 20;
[Link](`Sum = ${a + b}`);
Output
Sum = 30
Multi-line Strings
Without ES6
let text = "Hello\nWelcome\nJavaScript";
With Template Literals
let text = `Hello
Welcome
JavaScript`;
[Link](text);
Output
Hello
Welcome
JavaScript
Advantages
Cleaner syntax
Supports variables
Supports expressions
Supports multi-line strings
Easy to create HTML templates
Example:
let username = "Rahul";
let html = `
<h1>Welcome</h1>
<p>Hello ${username}</p>
`;
[Link](html);
Output
Welcome
Hello Rahul
3. Object and Array Destructuring
Destructuring is an ES6 feature that extracts values from arrays or properties from objects
and assigns them to variables in a concise way.
It makes code shorter and easier to read.
Array Destructuring
Without Destructuring
let colors = ["Red", "Green", "Blue"];
let first = colors[0];
let second = colors[1];
let third = colors[2];
[Link](first);
[Link](second);
[Link](third);
Output
Red
Green
Blue
With Destructuring
let colors = ["Red", "Green", "Blue"];
let [first, second, third] = colors;
[Link](first);
[Link](second);
[Link](third);
Output
Red
Green
Blue
Skipping Elements
let numbers = [10, 20, 30, 40];
let [a, , c] = numbers;
[Link](a);
[Link](c);
Output
10
30
Swapping Variables
let x = 5;
let y = 10;
[x, y] = [y, x];
[Link](x);
[Link](y);
Output
10
5
Object Destructuring
Without Destructuring
const student = {
name: "Rahul",
age: 22,
city: "Nashik"
};
let name = [Link];
let age = [Link];
[Link](name);
[Link](age);
Output
Rahul
22
With Destructuring
const student = {
name: "Rahul",
age: 22,
city: "Nashik"
};
const { name, age } = student;
[Link](name);
[Link](age);
Output
Rahul
22
Renaming Variables
const student = {
name: "Rahul",
age: 22
};
const { name: studentName, age: studentAge } = student;
[Link](studentName);
[Link](studentAge);
Output
Rahul
22
Nested Object Destructuring
const student = {
name: "Rahul",
address: {
city: "Nashik",
state: "Maharashtra"
}
};
const {
address: { city, state }
} = student;
[Link](city);
[Link](state);
Output
Nashik
Maharashtra
Advantages
Less code
Easy to extract values
Better readability
Useful in functions and React
Simplifies working with APIs
4. Default Parameters
Before ES6, if a function argument was not passed, its value became undefined.
ES6 introduced Default Parameters, allowing default values to be assigned to function
parameters when no argument is provided.
Syntax
function functionName(parameter = defaultValue) {
Without Default Parameter
function greet(name) {
[Link]("Hello " + name);
}
greet();
Output
Hello undefined
With Default Parameter
function greet(name = "Guest") {
[Link](`Hello ${name}`);
}
greet();
Output
Hello Guest
Passing Value
function greet(name = "Guest") {
[Link](`Hello ${name}`);
}
greet("Rahul");
Output
Hello Rahul
Multiple Default Parameters
function calculate(price = 0, quantity = 1) {
return price * quantity;
[Link](calculate());
[Link](calculate(200));
[Link](calculate(200, 5));
Output
0
200
1000
Default Parameter Using Another Parameter
function welcome(name, message = `Welcome ${name}`) {
[Link](message);
welcome("Amit");
Output
Welcome Amit
Advantages
Prevents undefined values
Makes functions more flexible
Reduces the need for manual checks
Improves code readability
Simplifies function calls
2.2 Advanced Operators and Modules (ES6)
ES6 (ECMAScript 2015) introduced many new features that make JavaScript easier to write,
understand, and maintain. Two important concepts are Spread and Rest Operators and
ES6 Modules (import/export).
1. Spread Operator (...)
Definition
The Spread Operator (...) expands (spreads) the elements of an array, object, or iterable
into individual elements.
It is mainly used to:
Copy arrays and objects
Merge arrays and objects
Pass array elements as function arguments
Create new arrays or objects without modifying the original ones
Syntax
...variable
Example 1: Spread Operator with Arrays
let numbers = [10, 20, 30];
[Link](...numbers);
Output
10 20 30
Here, the array elements are expanded into individual values.
Example 2: Copy an Array
let fruits = ["Apple", "Banana", "Mango"];
let copiedFruits = [...fruits];
[Link](copiedFruits);
Output
["Apple", "Banana", "Mango"]
Without the spread operator:
let copy = fruits;
Both variables refer to the same array.
Using spread creates a new copy.
Example 3: Merge Arrays
let arr1 = [1, 2];
let arr2 = [3, 4];
let result = [...arr1, ...arr2];
[Link](result);
Output
[1,2,3,4]
Example 4: Add New Elements
let numbers = [2,3,4];
let newNumbers = [1, ...numbers, 5];
[Link](newNumbers);
Output
[1,2,3,4,5]
Example 5: Spread Operator with Objects
let student = {
name: "Rahul",
age: 21
};
let newStudent = {
...student,
city: "Pune"
};
[Link](newStudent);
Output
{
name: "Rahul",
age: 21,
city: "Pune"
}
Example 6: Merge Objects
let personal = {
name: "Amit"
};
let professional = {
job: "Developer"
};
let details = {
...personal,
...professional
};
[Link](details);
Output
{
name: "Amit",
job: "Developer"
}
Example 7: Function Arguments
let numbers = [10,20,30];
function add(a,b,c){
return a+b+c;
}
[Link](add(...numbers));
Output
60
Advantages of Spread Operator
Makes code shorter.
Easy copying of arrays and objects.
Easy merging of arrays and objects.
Prevents accidental modification of original data.
Improves readability.
2. Rest Operator (...)
Definition
The Rest Operator (...) collects multiple values into a single array or object.
It is commonly used in:
Function parameters
Array destructuring
Object destructuring
Although it uses the same symbol (...) as the spread operator, its purpose is different.
Spread Operator Rest Operator
Expands elements Collects elements
Used on the right side Used on the left side
Example 1: Rest Parameters
function sum(...numbers){
let total = 0;
for(let num of numbers){
total += num;
}
return total;
}
[Link](sum(10,20));
[Link](sum(10,20,30,40));
Output
30
100
Here, all arguments are stored inside the array numbers.
Example 2: Array Destructuring
let colors = ["Red","Green","Blue","Black"];
let [first, second, ...others] = colors;
[Link](first);
[Link](second);
[Link](others);
Output
Red
Green
["Blue","Black"]
Example 3: Object Destructuring
let student = {
name: "Rahul",
age: 22,
city: "Pune"
};
let {name, ...details} = student;
[Link](name);
[Link](details);
Output
Rahul
{
age:22,
city:"Pune"
}
Example 4: Passing Unlimited Arguments
function display(...items){
[Link](items);
}
display("Pen","Book","Bag","Laptop");
Output
["Pen","Book","Bag","Laptop"]
Advantages of Rest Operator
Accepts any number of function arguments.
Simplifies function definitions.
Useful in destructuring.
Makes code cleaner.
Eliminates the need for the arguments object.
Difference Between Spread and Rest Operator
Spread Operator Rest Operator
Expands values Collects values
Spread Operator Rest Operator
Used to copy arrays Used to gather elements
Used when calling functions Used when defining functions
Used in arrays and objects Used in function parameters and destructuring
Creates copies and merges data Groups remaining elements into an array/object
3. ES6 Modules
ES6 Modules (introduced in ECMAScript 2015) provide a standard way to organize
JavaScript code into separate files called modules. A module is a JavaScript file that
contains related code, such as variables, functions, classes, or objects, which can be shared
with other files using the export and import keywords.
Before ES6, developers often wrote all JavaScript code in a single file or used external
libraries to manage code. This made large applications difficult to maintain. ES6 modules
solve this problem by allowing code to be split into multiple reusable files.
Definition
ES6 Modules allow JavaScript code to be divided into multiple files. Each file acts as a
separate module that can export variables, functions, classes, or objects and import them into
other files.
Modules help developers:
Organize code
Reuse code
Improve maintainability
Avoid global variable conflicts
Benefits of ES6 Modules
Better code organization
Reusable components
Easy maintenance
Avoids naming conflicts
Faster teamwork in large projects
Module Structure
A typical module-based project looks like this:
Project
│── [Link]
│── [Link]
│── [Link]
│── [Link]
[Link] → Contains mathematical functions.
[Link] → Contains message-related functions.
[Link] → Imports and uses modules.
[Link] → Loads the application.
Export Modules
The export keyword is used to make variables, functions, classes, or objects available to
other JavaScript files.
Without export, code cannot be accessed outside its own module.
Types of Export
There are two types:
1. Named Export
2. Default Export
1. Named Export
Named export allows exporting multiple variables, functions, or classes from a module.
Syntax
export variableName;
or
export function functionName() {
Example 1: Exporting Variables
[Link]
export const name = "Rahul";
export const age = 20;
export const city = "Pune";
[Link]
import { name, age, city } from "./[Link]";
[Link](name);
[Link](age);
[Link](city);
Output
Rahul
20
Pune
Example 2: Exporting Functions
[Link]
export function add(a, b) {
return a + b;
}
export function multiply(a, b) {
return a * b;
}
[Link]
import { add, multiply } from "./[Link]";
[Link](add(10, 5));
[Link](multiply(10, 5));
Output
15
50
Example 3: Exporting Classes
[Link]
export class Person {
constructor(name) {
[Link] = name;
}
display() {
[Link]([Link]);
}
[Link]
import { Person } from "./[Link]";
let p1 = new Person("Rahul");
[Link]();
Output
Rahul
Exporting Multiple Items Together
[Link]
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a - b;
}
const PI = 3.14;
export { add, subtract, PI };
Import
[Link]
import { add, subtract, PI } from "./[Link]";
[Link](add(5, 5));
[Link](subtract(10, 2));
[Link](PI);
2. Default Export
A default export is used when a module exports one main value.
Each module can have only one default export.
// [Link]
export default function greet(){
[Link]("Welcome to JavaScript");
}
Import:
// [Link]
import greet from "./[Link]";
greet();
Output
Welcome to JavaScript
Default Export with Variables
// [Link]
const company = "ABC Technologies";
export default company;
Import
import companyName from "./[Link]";
[Link](companyName);
Output
ABC Technologies
Import in ES6 Modules
The import keyword is used to access exported variables, functions, classes, or objects from
another module.
Without importing, exported code cannot be used in another file.
Syntax
Import Specific Members
import { memberName } from "./[Link]";
Import Multiple Members
import { add, subtract } from "./[Link]";
Import Default Export
import greet from "./[Link]";
Import Everything
import * as MathFunctions from "./[Link]";
Example
// [Link]
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
// [Link]
import * as MathFunctions from "./[Link]";
[Link]([Link](10, 20));
[Link]([Link](20, 10));
Output
30
10
Renaming Imported Members
Sometimes two modules contain functions with the same name.
Use as to rename.
import { add as sum } from "./[Link]";
[Link](sum(10, 20));
Combining Default and Named Exports
// [Link]
export const age = 22;
export function showAge(){
[Link](age);
}
export default "Rahul";
Import:
import personName, { age, showAge } from "./[Link]";
[Link](personName);
[Link](age);
showAge();
Output
Rahul
22
22
Difference Between Named Export and Default Export
Named Export Default Export
Multiple exports allowed Only one export allowed
Imported using {} Imported without {}
Must use the same exported name (unless aliased) Can use any name while importing
Example: export function add(){} Example: export default function(){}
Using Modules in HTML
To use ES6 modules in a web page, load the JavaScript file with type="module".
<!DOCTYPE html>
<html>
<head>
<title>ES6 Modules</title>
</head>
<body>
<script type="module" src="[Link]"></script>
</body>
</html>
Rules of ES6 Modules
Use export to make functions, variables, or classes available to other files.
Use import to access exported members from another module.
A file can have multiple named exports but only one default export.
Always include the correct relative file path (e.g., ./[Link]).
In browsers, load the main script with type="module".
2.3 Asynchronous JavaScript
Introduction to Asynchronous JavaScript
JavaScript is a single-threaded programming language, meaning it executes one statement
at a time. However, many operations such as fetching data from a server, reading files, or
waiting for user input take time. If JavaScript waited for these operations to finish before
executing the next statement, the webpage would freeze.
To solve this problem, JavaScript uses Asynchronous Programming, which allows long-
running tasks to execute in the background while the rest of the program continues.
Synchronous Example
[Link]("Start");
[Link]("Processing...");
[Link]("End");
Output
Start
Processing...
End
The statements execute one after another.
Asynchronous Example
[Link]("Start");
setTimeout(() => {
[Link]("Processing Completed");
}, 2000);
[Link]("End");
Output
Start
End
Processing Completed
The setTimeout() function schedules the task to execute after 2 seconds, allowing the rest of
the code to continue immediately.
1. Callback Concept and Limitations
A callback is a function passed as an argument to another function. The callback function is
executed after the first function completes its task.
Callbacks are widely used in asynchronous programming.
Syntax
function mainFunction(callback) {
// Perform some task
callback();
}
Example 1: Simple Callback
function greet(name, callback) {
[Link]("Hello " + name);
callback();
}
function goodbye() {
[Link]("Goodbye!");
}
greet("John", goodbye);
Output
Hello John
Goodbye!
Example 2: Callback with setTimeout()
[Link]("Start");
setTimeout(function () {
[Link]("Task Completed");
}, 3000);
[Link]("End");
Output
Start
End
Task Completed
Example 3: Callback after Calculation
function calculate(a, b, callback) {
let result = a + b;
callback(result);
}
calculate(10, 20, function(answer) {
[Link](answer);
});
Output
30
Advantages of Callbacks
Simple to understand.
Useful for asynchronous tasks.
Allows code reuse.
Prevents blocking of the main program.
Limitations of Callbacks
Although callbacks solve asynchronous problems, they introduce several issues.
1. Callback Hell
When many asynchronous operations depend on one another, callbacks become deeply
nested.
Example
function loginUser(callback) {
callback("Rahul");
}
function getProfile(user, callback) {
callback({
id: 101,
name: user
});
}
function getPosts(profile, callback) {
callback([
{ id: 1, title: "My First Post" }
]);
}
function getComments(posts, callback) {
callback([
"Nice post!",
"Very informative!"
]);
}
loginUser(function(user) {
getProfile(user, function(profile) {
getPosts(profile, function(posts) {
getComments(posts, function(comments) {
[Link](comments);
});
});
});
});
Output
[
'Nice post!',
'Very informative!'
]
This structure is difficult to read and maintain.
2. Difficult Error Handling
Each callback needs separate error handling.
Example:
function readFile(callback) {
callback(null, "Welcome to [Link]");
}
readFile(function(error, data){
if(error){
[Link](error);
return;
}
[Link](data);
});
readFile(function(error, data){
if(error){
[Link](error);
return;
}
[Link](data);
});
Output
Welcome to [Link]
Welcome to [Link]
Handling multiple callbacks becomes complicated.
3. Poor Readability
Large callback chains make the code confusing.
4. Difficult Debugging
Finding the source of an error in nested callbacks is difficult.
5. Code Maintenance
Updating callback-based applications becomes harder as project size increases.
Callback Hell Diagram
Task 1
|
Task 2
|
Task 3
|
Task 4
|
Task 5
In actual code it looks like:
callback(
callback(
callback(
callback()
)
)
)
This is called Pyramid of Doom.
2. Promises
A Promise is an object representing the eventual completion or failure of an asynchronous
operation.
Instead of nesting callbacks, promises provide cleaner and more manageable code.
A promise has three states.
Promise Lifecycle
Pending
/ \
/ \
Fulfilled Rejected
1. Pending
The operation has started but is not yet complete.
Example:
let promise = new Promise(function(resolve, reject){
});
The promise is waiting.
2. Fulfilled (Resolved)
The operation completed successfully.
Example
let promise = new Promise(function(resolve, reject){
resolve("Data Loaded");
});
[Link](function(result){
[Link](result);
});
Output
Data Loaded
3. Rejected
The operation failed.
Example
let promise = new Promise(function(resolve, reject){
reject("Network Error");
});
[Link](function(error){
[Link](error);
});
Output
Network Error
Creating a Promise
let promise = new Promise(function(resolve, reject){
let success = true;
if(success){
resolve("Success");
}
else{
reject("Failed");
}
});
Consuming a Promise
promise
.then(function(result){
[Link](result);
})
.catch(function(error){
[Link](error);
});
Example
let age = 20;
let checkAge = new Promise(function(resolve, reject){
if(age >= 18){
resolve("Eligible");
}
else{
reject("Not Eligible");
}
});
checkAge
.then(function(message){
[Link](message);
})
.catch(function(error){
[Link](error);
});
Output
Eligible
Promise Methods
Method Purpose
.then() Executes after successful completion
.catch() Handles errors
.finally() Executes regardless of success or failure
Example
fetchData()
.then(() => [Link]("Success"))
.catch(() => [Link]("Error"))
.finally(() => [Link]("Completed"));
3. Chaining Promises
Promise chaining means connecting multiple asynchronous operations using multiple .then()
methods.
The output of one promise becomes the input of the next promise.
Example 1
[Link](5)
.then(function(number){
return number * 2;
})
.then(function(number){
return number + 10;
})
.then(function(number){
[Link](number);
});
Output
20
Example 2
new Promise(function(resolve){
resolve(100);
})
.then(function(value){
[Link](value);
return value + 100;
})
.then(function(value){
[Link](value);
return value + 100;
})
.then(function(value){
[Link](value);
});
Output
100
200
300
Error Propagation
Errors automatically move down the promise chain until they are caught by .catch().
Example
[Link]()
.then(function(){
throw new Error("Something went wrong");
})
.then(function(){
[Link]("This will not execute");
})
.catch(function(error){
[Link]([Link]);
});
Output
Something went wrong
Instead of writing error handling for every .then(), one .catch() at the end can handle errors
from the entire chain.
Example
fetchUser()
.then(getOrders)
.then(getProducts)
.then(displayProducts)
.catch(function(error){
[Link]("Error:", error);
});
If any function fails, the .catch() block handles the error.
4. async / await
The async keyword makes a function asynchronous and automatically returns a promise.
Syntax
async function functionName(){
Example
async function message(){
return "Hello";
message().then([Link]);
Output
Hello
await
The await keyword pauses execution inside an async function until the promise is resolved
or rejected.
It can only be used inside an async function.
Example
function getData(){
return new Promise(function(resolve){
setTimeout(function(){
resolve("Data Received");
},2000);
});
async function display(){
let result = await getData();
[Link](result);
display();
Output (after 2 seconds)
Data Received
async / await Flow
Start
↓
Call async function
↓
await Promise
↓
Promise resolves
↓
Continue execution
↓
End
Comparison: Callback vs Promise vs async/await
Feature Callback Promise async/await
Readability Low Good Excellent
Nested Code High Low Very Low
Error Handling Difficult Easy with .catch() Easy with try...catch
Code Maintenance Difficult Easier Easiest
Chaining No Yes Yes
Simple asynchronous Multiple asynchronous Modern JavaScript
Best For
tasks tasks applications
Real-World Example: Fetching User Data
Using Callback
function getUser(callback) {
callback("Rahul");
}
function getOrders(user, callback) {
callback([101, 102]);
}
function getProducts(orders, callback) {
callback(["Laptop", "Mouse"]);
}
getUser(function(user) {
getOrders(user, function(orders) {
getProducts(orders, function(products) {
[Link](products);
});
});
});
Output
[ 'Laptop', 'Mouse' ]
Using Promises
function getUser() {
return [Link]("Rahul");
}
function getOrders(user) {
return [Link]([101, 102]);
}
function getProducts(orders) {
return [Link](["Laptop", "Mouse"]);
}
getUser()
.then(getOrders)
.then(getProducts)
.then([Link])
.catch([Link]);
Output
[ 'Laptop', 'Mouse' ]
Using async/await
function getUser() {
return [Link]("Rahul");
}
function getOrders(user) {
return [Link]([101, 102]);
}
function getProducts(orders) {
return [Link](["Laptop", "Mouse"]);
}
async function displayProducts() {
try {
const user = await getUser();
const orders = await getOrders(user);
const products = await getProducts(orders);
[Link](products);
} catch (error) {
[Link](error);
}
}
displayProducts();
Output
[ 'Laptop', 'Mouse' ]
try...catch Handling
Try-Catch is a JavaScript error-handling mechanism that allows you to handle runtime
errors without stopping the execution of the entire program.
Normally, if an error occurs in JavaScript, the program stops executing. By using try...catch,
you can catch the error, display a meaningful message, and allow the rest of the program to
continue running.
It is commonly used with:
File operations
JSON parsing
API requests
Asynchronous code (async/await)
User input validation
Syntax
try {
// Code that may produce an error
}
catch(error) {
// Code to handle the error
}
The try block contains the code that might generate an error.
If no error occurs:
The entire try block executes.
The catch block is skipped.
If an error occurs:
JavaScript immediately stops executing the remaining code inside the try block.
Control is transferred to the catch block.
The error object is passed to the catch block.
Flow Diagram
Start
│
▼
Execute try block
│
├──────────────┐
│ │
No Error Erro Occurs
│ │
▼ ▼
Continue Jump to catch
execution block
│ │
└──────┬───────┘
▼
Continue Program
Example : Error Occurs
try {
[Link]("Program Started");
let x = y + 10; // y is not defined
[Link](x);
}
catch(error) {
[Link]("An error occurred.");
}
[Link]("Program Ended");
Output
Program Started
An error occurred.
Program Ended
Using Finally Block
The finally block executes whether an error occurs or not.
It is generally used for cleanup tasks such as:
Closing files
Closing database connections
Stopping loaders
Releasing resources
Syntax
try {
}
catch(error) {
}
finally {
Example : Finally
try {
[Link]("Inside Try");
let x = a + 10;
}
catch(error) {
[Link]("Inside Catch");
}
finally {
[Link]("Inside Finally");
}
Output
Inside Try
Inside Catch
Inside Finally
Throw Statement
JavaScript allows you to create your own custom errors using the throw statement.
Syntax
throw "Error Message";
or
throw new Error("Invalid Input");
Example : Using Throw
let age = 15;
try {
if(age < 18){
throw new Error("You are not eligible to vote.");
}
[Link]("Eligible");
}
catch(error){
[Link]([Link]);
Output
You are not eligible to vote.
2.4 Logic-Building Programs
Logic-building programs help beginners develop problem-solving skills in JavaScript. They
involve creating algorithms using loops, conditions, variables, arrays, and functions. These
programs are commonly asked in interviews and programming exams.
1. Mathematical Logic
Mathematical logic programs use arithmetic operations, loops, and conditional statements to
solve mathematical problems.
A) Prime Number
Definition
A prime number is a positive integer greater than 1 that has exactly two factors:
1
Itself
Examples:
Prime Numbers: 2, 3, 5, 7, 11, 13, 17
Non-Prime Numbers: 4, 6, 8, 9, 10
Algorithm
1. Read the number.
2. If number ≤ 1, it is not prime.
3. Divide the number from 2 to n−1 (or √n).
4. If divisible by any number, it is not prime.
5. Otherwise, it is prime.
JavaScript Program
let num = 17;
let isPrime = true;
if (num <= 1) {
isPrime = false;
} else {
for (let i = 2; i < num; i++) {
if (num % i === 0) {
isPrime = false;
break;
}
}
}
if (isPrime) {
[Link](num + " is Prime");
} else {
[Link](num + " is Not Prime");
}
Output
17 is Prime
B) Factorial
Definition
The factorial of a positive integer is the product of all positive integers from 1 to n.
Formula:
n! = n × (n−1) × (n−2) × ... × 1
Example:
5! = 5 × 4 × 3 × 2 × 1 = 120
Algorithm
1. Read the number.
2. Initialize factorial = 1.
3. Multiply factorial by every number from 1 to n.
4. Display the result.
JavaScript Program
let num = 5;
let factorial = 1;
for (let i = 1; i <= num; i++) {
factorial *= i;
}
[Link]("Factorial =", factorial);
Output
Factorial = 120
Using Function
function factorial(n) {
let fact = 1;
for (let i = 1; i <= n; i++) {
fact *= i;
}
return fact;
}
[Link](factorial(6));
Output
720
C) Fibonacci Series
Definition
The Fibonacci sequence is a series in which each number is the sum of the previous two
numbers.
Sequence:
0 1 1 2 3 5 8 13 21 34...
Formula:
F(n) = F(n-1) + F(n-2)
Algorithm
1. Initialize first = 0, second = 1.
2. Print first and second.
3. Calculate next = first + second.
4. Update first and second.
5. Repeat until required terms are printed.
JavaScript Program
let n = 10;
let first = 0;
let second = 1;
[Link](first);
[Link](second);
for (let i = 3; i <= n; i++) {
let next = first + second;
[Link](next);
first = second;
second = next;
}
Output
0
1
1
2
3
5
8
13
21
34
Function Version
function fibonacci(n) {
let a = 0;
let b = 1;
for (let i = 1; i <= n; i++) {
[Link](a);
let temp = a + b;
a = b;
b = temp;
}
}
fibonacci(8);
2. Pattern Generation Using Loops
Pattern programs improve understanding of:
Nested loops
Loop control
Rows and columns
Conditions
Pattern 1: Square Pattern
Program
let n = 5;
for (let i = 1; i <= n; i++) {
let row = "";
for (let j = 1; j <= n; j++) {
row += "* ";
}
[Link](row);
}
Output
*****
*****
*****
*****
*****
Pattern 2: Right Triangle
let n = 5;
for (let i = 1; i <= n; i++) {
let row = "";
for (let j = 1; j <= i; j++) {
row += "* ";
}
[Link](row);
}
Output
*
**
***
****
*****
Pattern 3: Inverted Triangle
let n = 5;
for (let i = n; i >= 1; i--) {
let row = "";
for (let j = 1; j <= i; j++) {
row += "* ";
}
[Link](row);
}
Output
*****
****
***
**
*
Pattern 4: Number Triangle
let n = 5;
for (let i = 1; i <= n; i++) {
let row = "";
for (let j = 1; j <= i; j++) {
row += j + " ";
}
[Link](row);
}
Output
1
12
123
1234
12345
Pattern 5: Floyd's Triangle
let n = 5;
let num = 1;
for (let i = 1; i <= n; i++) {
let row = "";
for (let j = 1; j <= i; j++) {
row += num + " ";
num++;
}
[Link](row);
}
Output
1
23
456
7 8 9 10
11 12 13 14 15
Pattern 6: Pyramid Pattern
let n = 5;
for (let i = 1; i <= n; i++) {
let row = "";
for (let j = 1; j <= n - i; j++) {
row += " ";
}
for (let k = 1; k <= (2 * i - 1); k++) {
row += "*";
}
[Link](row);
}
Output
*
***
*****
*******
*********
3. Searching Fundamentals
Searching means finding a specific element in a collection of data (such as an array).
There are two common searching techniques:
1. Linear Search
2. Binary Search
A) Linear Search
Definition
Linear Search checks each element one by one until the desired element is found.
Steps
1. Start from the first element.
2. Compare with the target.
3. If found, return its position.
4. Otherwise, continue until the end.
Time Complexity
Best Case: O(1)
Average Case: O(n)
Worst Case: O(n)
JavaScript Program
let arr = [10, 20, 30, 40, 50];
let target = 30;
let found = false;
for (let i = 0; i < [Link]; i++) {
if (arr[i] === target) {
[Link]("Found at index", i);
found = true;
break;
}
}
if (!found)
[Link]("Not Found");
Output
Found at index 2
B) Binary Search
Definition
Binary Search divides the sorted array into halves to locate the target efficiently.
Note: Binary Search works only on sorted arrays.
Steps
1. Find the middle element.
2. Compare with the target.
3. If equal, stop.
4. If target is smaller, search the left half.
5. If target is larger, search the right half.
Time Complexity
Best Case: O(1)
Average Case: O(log n)
Worst Case: O(log n)
JavaScript Program
let arr = [10, 20, 30, 40, 50, 60];
let target = 40;
let left = 0;
let right = [Link] - 1;
while (left <= right) {
let mid = [Link]((left + right) / 2);
if (arr[mid] === target) {
[Link]("Found at index", mid);
break;
}
if (arr[mid] < target)
left = mid + 1;
else
right = mid - 1;
}
Output
Found at index 3
4. Sorting Fundamentals
Sorting is the process of arranging data in ascending or descending order.
Common sorting algorithms:
Bubble Sort
Selection Sort
Insertion Sort
Merge Sort
Quick Sort
For beginners, Bubble Sort is the easiest to understand.
Bubble Sort
Definition
Bubble Sort repeatedly compares adjacent elements and swaps them if they are in the wrong
order. After each pass, the largest element "bubbles up" to its correct position.
Steps
1. Compare adjacent elements.
2. Swap if needed.
3. Repeat until no swaps are required.
Time Complexity
Best Case: O(n) (already sorted with optimization)
Average Case: O(n²)
Worst Case: O(n²)
JavaScript Program
let arr = [5, 3, 8, 4, 2];
for (let i = 0; i < [Link] - 1; i++) {
for (let j = 0; j < [Link] - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
let temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
[Link](arr);
Output
[2, 3, 4, 5, 8]
JavaScript Built-in Sorting
JavaScript provides the sort() method to sort arrays.
let numbers = [50, 10, 40, 20, 30];
[Link]((a, b) => a - b);
[Link](numbers);
Output
[10, 20, 30, 40, 50]