0% found this document useful (0 votes)
34 views50 pages

JS Notes

Uploaded by

tejasmuradi1
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
34 views50 pages

JS Notes

Uploaded by

tejasmuradi1
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 50

################################################################################

HTML, CSS, Bootstrap and JS (2pm Batch) By Prasad


##############################################################################

JavaScript:
What is JavaScript?
JavaScript is a high-level, versatile programming language primarily used for adding
interactivity to web pages.
It can be run in web browsers to enhance user experience and also on server-side environments
(Node.js).
JavaScript is an essential part of web development, allowing developers to create dynamic and
responsive web applications.

History and Evolution of JavaScript:


JavaScript was created by Brendan Eich in 1995 at Netscape Communications Corporation.
Initially named "LiveScript," it was later renamed JavaScript as a marketing move to align with
Java's popularity.
ECMAScript, the standard specification for JavaScript, has evolved over the years, with ES6
(ECMAScript 2015) introducing significant enhancements.

Variables (var, let, const) in JavaScript:


Variables are a fundamental concept in JavaScript and other programming languages. They are
used to store and manage data. In JavaScript, there are three ways to declare variables: var, let,
and const. Each has its own characteristics, and the choice between them depends on the scope
and mutability requirements of the variable. Let's explore these three variable declaration
options in depth:
1. var:
var was the original way to declare variables in JavaScript. It has been largely replaced by let
and const in modern JavaScript code due to its quirks and limitations.
Function-Scoped: Variables declared with var are function-scoped, which means they are only
accessible within the function in which they are declared.
Hoisting: Variables declared with var are hoisted to the top of their containing function or the
global scope, which means they are available for use throughout the entire function or scope,
even before they are declared. However, their values are initialized to undefined until the actual
declaration is reached in the code.
Reassignment: Variables declared with var can be reassigned new values, even if they were
initially declared with a different data type.
Example:
function example() {
if (true) {
var x = 10;
}
console.log(x); // 10 (variable x is accessible outside the block)
}
2. let:
let was introduced in ECMAScript 6 (ES6) and is now the preferred way to declare variables
for most use cases.
Block-Scoped: Variables declared with let are block-scoped, which means they are only
accessible within the block in which they are declared (e.g., within { }).
Hoisting: Like var, variables declared with let are hoisted to the top of their containing block
but are not initialized until the declaration is reached. Accessing them before the declaration
results in a ReferenceError.
Reassignment: Variables declared with let can be reassigned new values, but their data type
cannot be changed after declaration.
Example:
function example() {
if (true) {
let y = 20;
}
console.log(y); // ReferenceError: y is not defined (block-scoped)
}
3. const:
const is used to declare variables whose values should not change after assignment. It is also
introduced in ES6.
Block-Scoped: Like let, variables declared with const are block-scoped.
Hoisting: Variables declared with const are also hoisted to the top of their containing block but,
similar to let, accessing them before declaration results in a ReferenceError.
Immutable: Variables declared with const cannot be reassigned to new values after the initial
assignment. However, it's important to note that objects and arrays declared with const can have
their properties or elements modified.
Example:
function example() {
const z = 30;
// z = 40; // Error: Assignment to constant variable
console.log(z); // 30
}
Choosing Between let and const:
Use let when you need a variable that can change its value over time.
Use const when you want to declare a variable with a value that should remain constant
throughout its scope. However, remember that for complex data types (like objects or arrays),
the variable itself is constant, but its properties or elements can be modified.
In modern JavaScript development, it's recommended to use let and const over var to write
more predictable and maintainable code. This is because let and const provide better scoping
rules and help prevent common programming errors related to variable reassignment.
JavaScript is a dynamically typed language, which means that variables are not explicitly
declared with data types. Instead, the data type of a variable is determined at runtime based on
the type of value it holds. JavaScript has several built-in data types, which can be categorized
into two main categories: primitive data types and reference data types.
Primitive Data Types:
These are basic data types that represent single values.
a. Number: Represents both integer and floating-point numbers. For example:
let num = 42;
let floatNum = 3.14;
b. String: Represents textual data enclosed in single (''), double ("") or backticks (``) quotes. For
example:
let greeting = "Hello, world!";
c. Boolean: Represents a binary value, either true or false.
let isTrue = true;
let isFalse = false;
d. Undefined: Represents a variable that has been declared but not assigned a value.
let undefinedVar;
e. Null: Represents an intention
al absence of any object value.
let emptyValue = null;
f. Symbol (ES6): Represents a unique and immutable value, primarily used as object property
keys.
const uniqueSymbol = Symbol("description");
g. BigInt (ES11): Represents large integers that cannot be represented by the Number data type.
const bigIntValue = 1234567890123456789012345678901234567890n;
Reference Data Types:
These are more complex data types that can hold multiple values and are stored as references in
memory.
a. Object: Represents a collection of key-value pairs, where keys are strings (or Symbols) and
values can be of any data type.
let person = {
name: "John",
age: 30,
};
b. Array: A specialized type of object used to store a collection of values in a sequential order.
let colors = ["red", "green", "blue"];
c. Function: Represents a reusable block of code that can be executed when invoked.
function greet(name) {
console.log(`Hello, ${name}!`);
}
d. Date: Represents a date and time.
let today = new Date();
e. RegExp: Represents a regular expression pattern.
let pattern = /[A-Z]/g;
These are the primary data types in JavaScript. Understanding these data types is essential for
working effectively with JavaScript variables and data.
In JavaScript, operators are symbols or keywords that perform operations on values (operands)
and produce a result. JavaScript has various types of operators that serve different purposes.
Here, I'll explain the main categories of operators in JavaScript:
Arithmetic Operators:
These operators perform mathematical operations on numeric operands.
Addition +: Adds two operands.
Subtraction -: Subtracts the right operand from the left operand.
Multiplication *: Multiplies two operands.
Division /: Divides the left operand by the right operand.
Remainder %: Returns the remainder of the division of the left operand by the right operand.
Increment ++: Increases the value of an operand by 1.
Decrement --: Decreases the value of an operand by 1.
Example:
let x = 5;
let y = 3;
let sum = x + y; // sum is 8
let product = x * y; // product is 15
x++; // x is now 6
Assignment Operators:
These operators assign a value to a variable.
Assignment =: Assigns a value to a variable.
Addition assignment +=: Adds the right operand to the variable and assigns the result.
Subtraction assignment -=: Subtracts the right operand from the variable and assigns the result.
Multiplication assignment *=: Multiplies the variable by the right operand and assigns the
result.
Division assignment /=: Divides the variable by the right operand and assigns the result.
Example:
let x = 5;
x += 3; // x is now 8
Comparison Operators:
These operators compare two values and return a Boolean result (true or false).
Equal to ==: Checks if two values are equal.
Not equal to !=: Checks if two values are not equal.
Strict equal to ===: Checks if two values are equal and have the same data type.
Strict not equal to !==: Checks if two values are not equal or have different data types.
Greater than >: Checks if the left operand is greater than the right operand.
Less than <: Checks if the left operand is less than the right operand.
Greater than or equal to >=: Checks if the left operand is greater than or equal to the right
operand.
Less than or equal to <=: Checks if the left operand is less than or equal to the right operand.
Example:
let a = 5;
let b = 3;
let isEqual = a === b; // isEqual is false
Logical Operators:
These operators perform logical operations on Boolean values and return Boolean results.
Logical AND &&: Returns true if both operands are true.
Logical OR ||: Returns true if at least one operand is true.
Logical NOT !: Negates the Boolean value of an operand.
Example:
let hasPermission = true;
let isLoggedIn = false;
let canAccess = hasPermission && isLoggedIn; // canAccess is false
Ternary (Conditional) Operator:
The ternary operator (? :) is a shorthand way to write conditional statements.
Example:
let age = 18;
let message = age >= 18 ? "You can vote" : "You cannot vote"; // message is "You can vote"
Bitwise Operators (Advanced):
These operators perform bitwise operations on binary representations of numbers. They are
typically used in low-level operations and are less commonly used in everyday JavaScript
development.
Bitwise AND &
Bitwise OR |
Bitwise XOR ^
Bitwise NOT ~
Left shift <<
Right shift >>
Zero-fill right shift >>>
Example:
let a = 5; // binary: 0101
let b = 3; // binary: 0011
let result = a & b; // result is 1 (binary: 0001)
These are the main categories of operators in JavaScript. Understanding how to use these
operators is crucial for performing various operations in your JavaScript code.
The operators I described above cover the most commonly used operators in JavaScript.
However, JavaScript does have a few more specialized operators that are used in specific
situations. Here are some additional operators you might encounter:
Typeof Operator:
The typeof operator returns a string representing the data type of a variable or expression.
Example:
let x = 42;
let typeOfX = typeof x; // typeOfX is "number"
Instanceof Operator:
The instanceof operator checks if an object is an instance of a particular class or constructor
function.
Example:
class Dog {}
let myDog = new Dog();
let isDog = myDog instanceof Dog; // isDog is true
In Operator:
The in operator checks if an object has a specific property.
Example:
let person = { name: "John", age: 30 };
let hasName = "name" in person; // hasName is true
Delete Operator:
The delete operator removes a property from an object.
Example:
let person = { name: "John", age: 30 };
delete person.age; // Removes the 'age' property
Comma Operator:
The comma operator allows you to evaluate multiple expressions and return the result of the
last one.
Example:
let a = 1, b = 2, c = 3;
let result = (a++, b++, c++); // result is 3 (the value of c)

Conditional (Ternary) Operator (?:):


I mentioned this operator earlier, but it's worth noting again. It's a shorthand way of writing
conditional expressions.
Example:
let age = 18;
let message = age >= 18 ? "You can vote" : "You cannot vote"; // message is "You can vote"
These additional operators are used in specific scenarios and might not be as commonly
encountered as the basic operators. However, they are part of the JavaScript language and can
be useful in the appropriate context.
Conditional statements in JavaScript allow you to execute different blocks of code depending
on whether a specified condition evaluates to true or false. JavaScript provides several
conditional statements, including if, else if, else, and switch. Let's explore how each of these
works in JavaScript:
if Statement:
The if statement is used to execute a block of code if a specified condition is true.
if (condition) {
// Code to execute if the condition is true
}
Example:
let age = 18;
if (age >= 18) {
console.log("You can vote.");
}
else if Statement:
The else if statement is used to specify a new condition to test if the previous if condition is
false. You can have multiple else if blocks after an initial if block.
if (condition1) {
// Code to execute if condition1 is true
} else if (condition2) {
// Code to execute if condition2 is true
} else {
// Code to execute if no conditions are true
}
Example:
let score = 85;
if (score >= 90) {
console.log("A grade");
} else if (score >= 80) {
console.log("B grade");
} else if (score >= 70) {
console.log("C grade");
} else {
console.log("D grade");
}
else Statement:
The else statement is used to execute a block of code if the condition in the preceding if or else
if statement(s) is false.
if (condition) {
// Code to execute if the condition is true
} else {
// Code to execute if the condition is false
}
Example:
let age = 15;
if (age >= 18) {
console.log("You can vote.");
} else {
console.log("You cannot vote.");
}
switch Statement:
The switch statement is used when you have a single value and want to execute different blocks
of code depending on its value. It's often used as an alternative to long chains of if and else if
statements.
switch (expression) {
case value1:
// Code to execute if expression is equal to value1
break;
case value2:
// Code to execute if expression is equal to value2
break;
// ...
default:
// Code to execute if expression doesn't match any case
}
Example:
let day = "Monday";
switch (day) {
case "Monday":
console.log("It's the start of the workweek.");
break;
case "Friday":
console.log("It's almost the weekend.");
break;
default:
console.log("It's some other day.");
}
These conditional statements are fundamental for controlling the flow of your JavaScript code
and allowing it to make decisions based on specific conditions. You can nest these statements,
combine them, and use them creatively to handle various scenarios in your programs.
Loops in JavaScript are used to repeatedly execute a block of code as long as a specified
condition is true or until a certain condition is met. JavaScript provides three primary types of
loops: for, while, and do...while. Each type has its use cases and syntax.
for Loop:
The for loop is used when you know the number of iterations you want to perform. It consists
of three parts: initialization, condition, and increment (or decrement).
for (initialization; condition; increment) {
// Code to execute in each iteration
}
Example:
for (let i = 0; i < 5; i++) {
console.log(`Iteration ${i}`);
}
while Loop:
The while loop is used when you want to execute a block of code as long as a condition is true.
The condition is checked before each iteration.
while (condition) {
// Code to execute as long as the condition is true
}
Example:
let count = 0;
while (count < 3) {
console.log(`Count is ${count}`);
count++;
}
do...while Loop:
The do...while loop is similar to the while loop, but the condition is checked after the block of
code is executed, meaning the code block is guaranteed to run at least once.
do {
// Code to execute at least once
} while (condition);
Example:
let x = 5;
do {
console.log(`x is ${x}`);
x--;
} while (x > 0);
When choosing between these loop types, consider the following:
Use a for loop when you know the number of iterations in advance.
Use a while loop when you want to loop based on a condition that may change during
execution.
Use a do...while loop when you want to ensure that the loop body runs at least once before
checking the condition.
You can also use loop control statements like break and continue to control the flow within
loops. break is used to exit a loop prematurely, and continue is used to skip the current iteration
and move to the next one. These statements can be helpful for fine-tuning the behavior of your
loops.
In JavaScript, the for loop is a versatile construct for iterating over various types of data
structures and sequences. There are several ways to use the for loop, each tailored to different
use cases:
Standard for Loop:
The standard for loop is the most common way to iterate over a range of values. It consists of
three expressions within parentheses: initialization, condition, and iteration.
for (initialization; condition; iteration) {
// Code to execute in each iteration
}
Example:
for (let i = 0; i < 5; i++) {
console.log(`Iteration ${i}`);
}
for...in Loop:
The for...in loop is used to iterate over the properties (keys) of an object. It's not recommended
for iterating over arrays or other iterable objects, as it may not guarantee a specific order of
iteration.
for (let key in object) {
// Code to execute for each property of the object
}
Example:
const person = { name: "John", age: 30 };
for (let key in person) {
console.log(`${key}: ${person[key]}`);
}
for...of Loop:
The for...of loop is introduced in ES6 (ECMAScript 2015) and is used to iterate over iterable
objects like arrays, strings, and more. It provides a more concise way to iterate compared to the
for...in loop.
for (let element of iterable) {
// Code to execute for each element in the iterable
}
Example:
const colors = ["red", "green", "blue"];
for (let color of colors) {
console.log(color);
}
forEach Method:
For arrays, you can use the forEach method to iterate over elements. It takes a callback function
as an argument and executes that function for each element in the array.
array.forEach(function (element, index, array) {
// Code to execute for each element in the array
});
Example:
const numbers = [1, 2, 3];
numbers.forEach(function (number) {
console.log(number);
});
for...await...of Loop (for Asynchronous Iteration):
In modern JavaScript, when dealing with asynchronous code and Promises, you can use the
for...await...of loop to iterate over asynchronously iterable objects.
for await (let element of asynchronousIterable) {
// Code to execute for each element in the asynchronously iterable
}
Example (using asynchronous Promises):
const asyncValues = [fetch("url1"), fetch("url2")];
for await (let response of asyncValues) {
const data = await response.json();
console.log(data);
}
Each of these for loop variations serves a specific purpose, so choose the one that best fits your
needs based on the type of data you are iterating over and the desired behavior of your loop.
3.1. Working with Strings:
Introduction:
Strings are sequences of characters enclosed in single (' '), double (" "), or backticks (` `) quotes.
JavaScript provides various methods and techniques for working with strings.
3.1.1. String Manipulation:
3.1.1.1. Concatenation:
Concatenation is the process of combining two or more strings into a single string.
In JavaScript, you can concatenate strings using the + operator or the .concat() method.
Example using the + operator:
const firstName = 'John';
const lastName = 'Doe';
const fullName = firstName + ' ' + lastName;
3.1.1.2. String Interpolation:
String interpolation is a way to embed variables or expressions within a string.
In JavaScript, you can use template literals (enclosed in backticks) to achieve string
interpolation.
Example using template literals:
const age = 30;
const message = `I am ${age} years old.`;
3.1.2. String Methods:
3.1.2.1. Common String Methods:
a. charAt(index):
Returns the character at the specified index in the string.
Indexing starts from 0.
Example:
const str = 'Hello';
const character = str.charAt(1); // character will be 'e'
b. indexOf(substring):
Returns the index of the first occurrence of the specified substring in the string.
Returns -1 if the substring is not found.
Example:
const sentence = 'The quick brown fox';
const index = sentence.indexOf('quick'); // index will be 4
c. length:
Returns the length (number of characters) of a string.
Example:
const word = 'JavaScript';
const length = word.length; // length will be 10
3.1.2.2. String Manipulation with Methods:
a. toUpperCase() and toLowerCase():
toUpperCase() converts all characters in a string to uppercase.
toLowerCase() converts all characters in a string to lowercase.
Example:
const text = 'Hello, World!';
const uppercaseText = text.toUpperCase(); // 'HELLO, WORLD!'
const lowercaseText = text.toLowerCase(); // 'hello, world!'
b. trim():
trim() removes leading and trailing whitespace (spaces, tabs, and line breaks) from a string.
Example:
const userInput = ' Hello, ';
const trimmedInput = userInput.trim(); // 'Hello,'
3.2. Working with Numbers:
Introduction:
JavaScript supports various numeric data types, including integers and floating-point numbers.
You can perform arithmetic operations and manipulate numbers using built-in functions and
methods.
3.2.1. Math Object:
3.2.1.1. Math Functions:
a. Math.round(number):
Math.round() rounds a number to the nearest integer.
Example:
const num = 4.6;
const rounded = Math.round(num); // rounded will be 5
b. Math.floor(number):
Math.floor() rounds a number down to the nearest integer.
Example:
const num = 4.9;
const floored = Math.floor(num); // floored will be 4
c. Math.random():
Math.random() generates a random floating-point number between 0 (inclusive) and 1
(exclusive).
Example to get a random number between 1 and 10:
const randomNumber = Math.floor(Math.random() * 10) + 1;
3.2.2. Number Methods:
3.2.2.1. Converting Strings to Numbers:
a. parseInt(string):
parseInt() parses a string and returns an integer.
It stops parsing when it encounters a non-digit character.
Example:
const numberString = '123';
const parsedInt = parseInt(numberString); // parsedInt will be 123
b. parseFloat(string):
parseFloat() parses a string and returns a floating-point number.
It stops parsing when it encounters a non-digit character.
Example:
const floatString = '3.14';
const parsedFloat = parseFloat(floatString); // parsedFloat will be 3.14
3.2.2.2. Number Formatting:
a. toFixed(decimalPlaces):
toFixed() formats a number with a specified number of decimal places and returns it as a string.
Example:
const value = 3.14159265359;
const formattedValue = value.toFixed(2); // formattedValue will be '3.14'
b. toPrecision(precision):
toPrecision() formats a number with a specified precision (total number of significant digits)
and returns it as a string.
Example:
const number = 123.456789;
const formattedNumber = number.toPrecision(4); // formattedNumber will be '123.5'
3.3. Arrays:
Introduction:
An array is a data structure in JavaScript that stores a collection of values or elements.
Arrays can hold various data types, including numbers, strings, objects, and even other arrays.
JavaScript provides a range of methods to work with arrays efficiently.
3.3.1. Declaring and Initializing Arrays:
3.3.1.1. Array Literals:
An array literal is the simplest way to create an array.
It involves enclosing elements within square brackets [ ], separated by commas.
Example:
const fruits = ['apple', 'banana', 'orange'];
3.3.1.2. Creating Arrays with the Array Constructor:
You can also create arrays using the Array constructor.
Pass the elements as arguments to the Array constructor.
Example:
const colors = new Array('red', 'green', 'blue');
3.3.2. Array Methods:
3.3.2.1. Iterating Through Arrays:
a. forEach(callback):
forEach() method iterates through each element of the array and applies the provided callback
function to each element.
Example:
const numbers = [1, 2, 3, 4, 5];
numbers.forEach((number) => {
console.log(number);
});
b. map(callback):
map() method creates a new array by applying the provided callback function to each element
of the original array.
Example:
const numbers = [1, 2, 3, 4, 5];
const doubledNumbers = numbers.map((number) => number * 2);
c. filter(callback):
filter() method creates a new array with all elements that pass the test provided by the callback
function.
Example:
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter((number) => number % 2 === 0);
3.3.2.2. Modifying Arrays:
a. push(element) and pop():
push() adds one or more elements to the end of the array.
pop() removes the last element from the end of the array.
Example:
const fruits = ['apple', 'banana', 'orange'];
fruits.push('grape'); // Adds 'grape' to the end
const removedFruit = fruits.pop(); // Removes 'grape'
b. shift() and unshift(element):
shift() removes the first element from the beginning of the array.
unshift() adds one or more elements to the beginning of the array.
Example:
const colors = ['red', 'green', 'blue'];
colors.shift(); // Removes 'red'
colors.unshift('yellow'); // Adds 'yellow' to the beginning
c. splice(startIndex, deleteCount, elements):
splice() can add, remove, or replace elements in an array at a specified index.
startIndex is the index at which to start the modification.
deleteCount is the number of elements to remove (optional).
elements are the elements to add (optional).
Example:
const numbers = [1, 2, 3, 4, 5];
numbers.splice(2, 1); // Removes the element at index 2 (3)
numbers.splice(1, 0, 6, 7); // Inserts 6 and 7 at index 1
3.4. Objects:
Introduction:
Objects are complex data structures in JavaScript that allow you to group related data and
functions together.
Objects consist of properties (key-value pairs) and methods (functions associated with the
object).
3.4.1. Creating Objects:
3.4.1.1. Object Literals:
An object literal is the simplest way to create an object.
It involves enclosing properties and methods within curly braces { }, separated by commas.
Example:
const person = {
firstName: 'John',
lastName: 'Doe',
age: 30,
sayHello: function() {
console.log('Hello!');
}
};
3.4.1.2. Constructor Functions and Classes:
You can also create objects using constructor functions or ES6 classes.
Constructor functions initialize objects with predefined properties and methods.
Classes provide a more structured way to create objects in modern JavaScript.
Example using a constructor function:
function Person(firstName, lastName, age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.sayHello = function() {
console.log('Hello!');
};
}
const person = new Person('John', 'Doe', 30);
3.4.2. Object Properties and Methods:
3.4.2.1. Accessing and Modifying Properties:
a. Accessing Properties:
You can access object properties using dot notation (object.property) or bracket notation
(object['property']).
Example:
console.log(person.firstName); // 'John'
console.log(person['lastName']); // 'Doe'
b. Modifying Properties:
Object properties can be modified by assigning new values.
Example:
person.age = 35; // Modifying the 'age' property
3.4.2.2. Adding Methods to Objects:
Methods are functions defined within an object.
They can be used to perform actions related to the object's properties.
Example:
const person = {
firstName: 'John',
lastName: 'Doe',
sayHello: function() {
console.log(`Hello, my name is ${this.firstName} ${this.lastName}.`);
}
};
person.sayHello(); // 'Hello, my name is John Doe.'
3.4.2.3. Object Destructuring:
Object destructuring allows you to extract properties from an object and assign them to
variables.
Example:
const person = {
firstName: 'John',
lastName: 'Doe',
age: 30
};
const { firstName, lastName } = person;
console.log(firstName); // 'John'
console.log(lastName); // 'Doe'

DOM (Document Object Model) manipulation in JavaScript is the process of interacting with and modifying
the structure, content, and style of a web page or document represented in the form of a tree-like structure
called the DOM tree. The DOM represents every element on a web page as an object, allowing you to access
and manipulate them using JavaScript. Here's a detailed explanation of DOM manipulation in JavaScript::

 To manipulate elements, you first need to access them. You can use several methods to do this:
 document.getElementById(id): Retrieves an element with the specified id attribute.
 document.getElementsByClassName(className): Returns an array-like collection of elements with the
specified class name.
 document.getElementsByTagName(tagName): Returns an array-like collection of elements with the
specified tag name.
 document.querySelector(selector): Retrieves the first element that matches the specified CSS selector.
 document.querySelectorAll(selector): Retrieves all elements that match the specified CSS selector.

Example:
// Accessing elements by ID
const header = document.getElementById('header');

// Accessing elements by class name


const buttons = document.getElementsByClassName('btn');

// Accessing elements by tag name


const paragraphs = document.getElementsByTagName('p');

// Accessing elements using CSS selectors


const firstButton = document.querySelector('.btn:first-of-type');
const allLinks = document.querySelectorAll('a');:

 Once you have access to an element, you can modify its properties, such as text content, attributes, and
CSS styles.

Example:

// Changing text content


header.textContent = 'New Header Text';

// Modifying attributes
const link = document.querySelector('a');
link.setAttribute('href', 'https://example.com&#39;);

// Changing CSS styles


header.style.backgroundColor = 'blue';
You can create new elements and add them to the DOM or remove existing elements.
Example:
// Creating a new element
const newDiv = document.createElement('div');
newDiv.textContent = 'Newly created div';
document.body.appendChild(newDiv);

// Removing an element
const elementToRemove = document.getElementById('toBeRemoved');
elementToRemove.parentNode.removeChild(elementToRemove);:

 You can attach event listeners to DOM elements to respond to user interactions (e.g., clicks, input,
mouse events).

Example:

const button = document.getElementById('myButton');


button.addEventListener('click', function() {
alert('Button clicked!');
});
:
 You can traverse the DOM tree to navigate between parent, child, and sibling elements.

Example:

const parent = document.getElementById('parent');


const firstChild = parent.firstElementChild;
const nextSibling = firstChild.nextElementSibling;
:

 You can add, remove, or toggle CSS classes on elements to control their styling.

Example:

const element = document.getElementById('myElement');


element.classList.add('active');
element.classList.remove('inactive');
element.classList.toggle('highlight');

 You can manipulate form elements, retrieve user input, and submit forms using JavaScript.

Example:

const form = document.getElementById('myForm');


form.addEventListener('submit', function(event) {
event.preventDefault(); // Prevents the form from submitting
const inputValue = document.getElementById('inputField').value;
console.log('Input value:', inputValue);
});

DOM manipulation is a fundamental aspect of web development with JavaScript, and it allows you to create
dynamic and interactive web applications by changing the content and behavior of web pages based on user
actions and data from external sources.
1. Querying Elements:

getElementById: This method allows you to select an element by its unique id attribute. It returns a reference to
the first element with the specified ID. For example:

const element = document.getElementById('myElement');

getElementsByClassName: This method selects elements by their class name and returns a collection
(HTMLCollection) of elements with the specified class. For example:

const elements = document.getElementsByClassName('myClass');

getElementsByTagName: This method selects elements by their HTML tag name and returns a collection of
elements with that tag name. For example:

const elements = document.getElementsByTagName('p');

querySelector: This method allows you to select elements using CSS selector syntax and returns the first
matching element. It is versatile and can select elements by tag name, class, ID, or other attributes. For
example:

const element = document.querySelector('.myClass');

querySelectorAll: Similar to querySelector, this method selects elements using CSS selector syntax but returns
a NodeList containing all matching elements. For example:

const elements = document.querySelectorAll('p.myClass');


2. Traversing the DOM:

Parent, Child, and Sibling Relationships: DOM elements are organized in a hierarchical structure, and you can
navigate through them using various properties and methods.

parentNode: This property returns the parent node (element) of a given element. For example:

const child = document.getElementById('myChildElement');

const parent = child.parentNode;

children: This property returns a live HTMLCollection of child elements of a given parent element. It includes
only element nodes, excluding text and comment nodes. For example:

const parent = document.getElementById('myParentElement');

const childElements = parent.children;

firstChild and lastChild: These properties return the first and last child nodes of an element, including text and
comment nodes. To get the first and last child elements, you may need to navigate through text and comment
nodes if they exist. For example:

const parent = document.getElementById('myParentElement');


const firstChildElement = parent.firstChild;
const lastChildElement = parent.lastChild;

These properties and methods are valuable for navigating the DOM tree, accessing parent and child elements,
and manipulating the structure of web pages dynamically. They are essential tools for interacting with the
HTML structure of a document in JavaScript.

Certainly! Modifying DOM elements is a critical part of working with web pages dynamically in JavaScript.
Here's an explanation of how to change content, modify attributes, add/remove classes, modify styles, and
clone/delete elements:

1. Changing Content:

textContent: The textContent property allows you to get or set the text content of an element. It represents the
text inside an element, excluding HTML tags. For example:

const element = document.getElementById('myElement');


console.log(element.textContent); // Get text content
element.textContent = 'New text content'; // Set text content

innerHTML: The innerHTML property allows you to get or set the HTML content of an element, including
HTML tags. Be cautious when using it, as it can introduce security risks if you insert untrusted content. For
example:

const element = document.getElementById('myElement');


console.log(element.innerHTML); // Get HTML content
element.innerHTML = '<p>New HTML content</p>'; // Set HTML content
innerText: Similar to textContent, the innerText property allows you to get or set the text content of an element,
but it respects the CSS styling and might not include text that is visually hidden. For example:

const element = document.getElementById('myElement');


console.log(element.innerText); // Get text content
element.innerText = 'New text content'; // Set text content

2. Modifying Attributes:

getAttribute: The getAttribute method allows you to retrieve the value of an HTML attribute for an element. For
example:

const element = document.getElementById('myElement');


const value = element.getAttribute('src');

setAttribute: The setAttribute method lets you set or change the value of an HTML attribute for an element. For
example:

const element = document.getElementById('myElement');


element.setAttribute('src', 'new-image.jpg');
removeAttribute: The removeAttribute method removes an attribute from an element. For example:

const element = document.getElementById('myElement');


element.removeAttribute('src');

3. Adding and Removing Classes:

classList.add: The classList.add method allows you to add one or more CSS classes to an element. For example:

const element = document.getElementById('myElement');


element.classList.add('active', 'highlight');

classList.remove: The classList.remove method removes one or more CSS classes from an element. For
example:
const element = document.getElementById('myElement');
element.classList.remove('inactive', 'highlight');

classList.toggle: The classList.toggle method adds a class if it's not present and removes it if it is. It can also
take a second argument to control the addition/removal based on a condition. For example:
const element = document.getElementById('myElement');
element.classList.toggle('active'); // Toggles the 'active' class
element.classList.toggle('highlight', shouldHighlight); // Toggles the 'highlight' class based on 'shouldHighlight'
condition

4. Modifying Styles:

style property: The style property of an element allows you to directly manipulate its inline CSS styles. You can
get or set specific style properties like element.style.color, element.style.fontSize, and more. For example:const
element = document.getElementById('myElement');
element.style.color = 'red'; // Set the text color to red
element.style.fontSize = '20px'; // Set the font size to 20 pixels

5. Cloning and Deleting Elements:

cloneNode: The cloneNode method creates a copy of an element, including all of its attributes and child nodes.
You can specify whether to clone only the element (shallow copy) or its descendants as well (deep copy). For
example:

const originalElement = document.getElementById('myElement');


const clonedElement = originalElement.cloneNode(true); // Deep copy

remove: The remove method removes an element from the DOM. It is used to delete an element and its
associated data. For example:

const element = document.getElementById('myElement');


element.remove();
These DOM manipulation techniques are essential for creating dynamic and interactive web pages in
JavaScript. They allow you to change the content, appearance, and behavior of HTML elements, enabling you
to build feature-rich web applications.

1. Creating Elements:

document.createElement: The document.createElement method allows you to create a new HTML element in
memory. You can specify the element type (e.g., 'div', 'p', 'span') and then manipulate its properties and
attributes before inserting it into the DOM. For example:

const newDiv = document.createElement('div');


newDiv.textContent = 'Newly created div element';

2. Inserting Elements:

appendChild: The appendChild method is used to insert a new element as the last child of another element. It
adds the specified element as the last child of the target element. For example:

const parentElement = document.getElementById('parent');


parentElement.appendChild(newDiv);

insertBefore: The insertBefore method allows you to insert an element before a specific reference element (i.e.,
before an existing child element). It takes two arguments: the new element and the reference element. For
example:
const parentElement = document.getElementById('parent');
const referenceElement = document.getElementById('reference');
parentElement.insertBefore(newDiv, referenceElement);

replaceChild: The replaceChild method is used to replace an existing child element with a new one. It takes two
arguments: the new element and the element to be replaced. For example:

const parentElement = document.getElementById('parent');


const oldElement = document.getElementById('oldChild');
parentElement.replaceChild(newDiv, oldElement);

3. Creating and Inserting Multiple Elements:

Creating Document Fragments: When you need to create and insert multiple elements efficiently, it's
recommended to use document fragments. A document fragment is an in-memory container for a group of
DOM nodes. You can create elements, append them to the fragment, and then insert the entire fragment into the
DOM. This reduces the number of DOM manipulation operations, improving performance. For example:

const fragment = document.createDocumentFragment();


for (let i = 0; i < 10; i++) {
const newDiv = document.createElement('div');
newDiv.textContent = `Element ${i}`;
fragment.appendChild(newDiv);
}
const parentElement = document.getElementById('parent');
parentElement.appendChild(fragment);

4. Templating with Libraries:

Using Template Libraries: Instead of manually creating and manipulating elements, you can use templating
libraries like Handlebars or Mustache. These libraries allow you to define templates with placeholders, and then
you provide data to render the templates into HTML. Templating libraries simplify the process of generating
HTML content dynamically and help separate data from presentation.

Example using Handlebars:

// Define a Handlebars template


const source = document.getElementById('my-template').innerHTML;
const template = Handlebars.compile(source);

// Data to render the template


const context = { name: 'John', age: 30 };

// Render the template with data


const html = template(context);

// Insert the rendered HTML into the DOM


const container = document.getElementById('container');
container.innerHTML = html;

1. Adding Event Listeners:

addEventListener: The addEventListener method is used to attach an event listener to an HTML element. It
allows you to specify the type of event you want to listen for and the function that should be executed when the
event occurs. For example:

const button = document.getElementById('myButton');

button.addEventListener('click', function () {
alert('Button clicked!');
});
2. Event Object:

Accessing Event Properties: When an event occurs, an event object is created. This object contains information
about the event, such as the target element, the type of event, mouse coordinates, and more. You can access
event properties using the event object. For example:

const button = document.getElementById('myButton');

button.addEventListener('click', function (event) {


console.log('Event type:', event.type);
console.log('Target element:', event.target);
console.log('Mouse X-coordinate:', event.clientX);
console.log('Mouse Y-coordinate:', event.clientY);
});
3. Event Bubbling and Capturing:

Understanding Event Flow: In the DOM, events follow a propagation flow known as event bubbling and event
capturing. By default, events bubble from the target element up the DOM tree to the root (capturing phase) and
then back down to the target element (bubbling phase). Understanding this flow is important for managing
event handlers, especially when multiple elements are nested.

Event Bubbling: During the bubbling phase, the event starts at the target element and bubbles up to the root of
the document. You can use event bubbling to catch events on parent elements instead of attaching separate
event listeners to each child element.

Event Capturing: Event capturing is the opposite of bubbling. It occurs during the capturing phase, where the
event starts at the document root and trickles down to the target element. Event capturing is less commonly
used than bubbling but can be helpful in certain scenarios.

To specify whether you want to use event capturing or bubbling, you can pass an options object as the third
argument to addEventListener. For example:
const button = document.getElementById('myButton');

button.addEventListener('click', function () {
console.log('Button clicked!');
}, { capture: true }); // Use event capturing
4. Event Delegation:

Handling Events on Parent Elements for Efficiency: Event delegation is a technique where you attach a single
event listener to a common ancestor (e.g., a parent element) of multiple child elements you want to handle
events for. When an event occurs on a child element, it bubbles up to the parent, and you can identify the target
child element from the event object. Event delegation is efficient when dealing with a large number of elements
or dynamically created elements.
Example of event delegation:

const parentList = document.getElementById('parentList');

parentList.addEventListener('click', function (event) {


if (event.target.tagName === 'LI') {
// Handle the click on the list item
event.target.classList.toggle('selected');
}
});
Event handling is crucial for building interactive web applications, and these techniques help you manage
events efficiently and respond to user interactions effectively. Understanding event flow, event objects, and
event delegation is essential for mastering event handling in JavaScript.
5.1. Understanding Asynchronous Programming
5.1.1. Callbacks
5.1.1.1. Asynchronous Code with Callbacks:
Asynchronous programming in JavaScript is a way to handle tasks that might take a variable amount of time to
complete.
Callbacks are functions that are passed as arguments to other functions and are executed when those functions
complete their tasks.
Example of asynchronous code with callbacks:

function fetchData(callback) {
setTimeout(function() {
const data = 'This is some data.';
callback(data);
}, 2000);
}
function processData(data) {
console.log('Processed data:', data);
}
fetchData(processData);
5.1.1.2. Callback Hell and Its Issues:
Callback hell, also known as the "pyramid of doom," occurs when you have multiple nested
callbacks.
It makes code hard to read, debug, and maintain.
Example of callback hell:
function step1(callback) {
setTimeout(function() {
console.log('Step 1 completed.');
callback();
}, 1000);
}
function step2(callback) {
setTimeout(function() {
console.log('Step 2 completed.');
callback();
}, 1000);
}
function step3(callback) {
setTimeout(function() {
console.log('Step 3 completed.');
callback();
}, 1000);
}
step1(function() {
step2(function() {
step3(function() {
console.log('All steps completed.');
});
});
});
5.1.2. Promises
5.1.2.1. Creating and Using Promises:
Promises provide a cleaner way to handle asynchronous operations.
A promise represents a value that may be available now, in the future, or never.
Promises can be in one of three states: pending, resolved (fulfilled), or rejected.
Example of creating and using promises:
function fetchData() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
const data = 'This is some data.';
if (data) {
resolve(data);
} else {
reject('Error: Data not found.');
}
}, 2000);
});
}
fetchData()
.then(function(data) {
console.log('Resolved:', data);
})
.catch(function(error) {
console.error('Rejected:', error);
});
5.1.2.2. Chaining Promises:
Promises can be chained together to execute asynchronous operations sequentially.
Example of chaining promises:
function step1() {
return new Promise(function(resolve) {
setTimeout(function() {
console.log('Step 1 completed.');
resolve('Result from Step 1');
}, 1000);
});
}
function step2(data) {
return new Promise(function(resolve) {
setTimeout(function() {
console.log('Step 2 completed with data:', data);
resolve('Result from Step 2');
}, 1000);
});
}
function step3(data) {
return new Promise(function(resolve) {
setTimeout(function() {
console.log('Step 3 completed with data:', data);
resolve('Result from Step 3');
}, 1000);
});
}
step1()
.then(step2)
.then(step3)
.then(function(result) {
console.log('All steps completed with result:', result);
});
5.2. Fetch API and AJAX
5.2.1. Making HTTP Requests
5.2.1.1. Using the Fetch API:
The Fetch API is a modern JavaScript API for making HTTP requests in a more flexible and
efficient way.
It uses Promises to handle responses and provides a simpler syntax than older AJAX methods.
Example of using the Fetch API to make a GET request:
fetch('https://api.example.com/data')
.then(function(response) {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json(); // Parse response as JSON
})
.then(function(data) {
console.log('Data received:', data);
})
.catch(function(error) {
console.error('Error:', error);
});
5.2.1.2. Handling Different HTTP Methods (GET, POST):
The Fetch API allows you to specify different HTTP methods when making requests.
GET requests are used to retrieve data, while POST requests are used to send data to a server.
Example of making a POST request with the Fetch API:
fetch('https://api.example.com/post-data', {
method: 'POST',
headers: {
'Content-Type': 'application/json', // Specify content type
},
body: JSON.stringify({ username: 'john_doe', password: 'secure123' }), // Convert data to
JSON
})
.then(function(response) {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(function(data) {
console.log('Data received:', data);
})
.catch(function(error) {
console.error('Error:', error);
});
5.2.2. Handling Responses
5.2.2.1. Parsing JSON Responses:
When working with APIs, responses are often in JSON format.
You can parse JSON responses using the .json() method.
Example of parsing JSON responses with the Fetch API:
fetch('https://api.example.com/data')
.then(function(response) {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json(); // Parse response as JSON
})
.then(function(data) {
console.log('Data received:', data);
})
.catch(function(error) {
console.error('Error:', error);
});
5.2.2.2. Error Handling with Fetch:
Error handling is essential when making HTTP requests.
You can use the .catch() method to handle errors and network issues.
Example of error handling with the Fetch API:
fetch('https://api.example.com/data')
.then(function(response) {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(function(data) {
console.log('Data received:', data);
})
.catch(function(error) {
console.error('Error:', error);
});
Module 6: Error Handling and Debugging
6.1. Handling Errors
6.1.1. try...catch Statements
6.1.1.1. Handling Exceptions Gracefully:
JavaScript allows you to use try...catch statements to handle errors gracefully.
Code within the try block is executed, and if an exception (error) occurs, it's caught and handled
in the catch block.
Example of using try...catch to handle an error:
try {
// Code that might throw an error
const result = undefinedVariable + 5;
console.log('This will not be reached.');
} catch (error) {
console.error('An error occurred:', error.message);
}
6.1.1.2. Catching Specific Error Types:
You can catch specific types of errors by checking the error object's type in the catch block.
Example of catching a specific type of error:
try {
// Code that might throw an error
const result = undefinedVariable + 5;
console.log('This will not be reached.');
} catch (error) {
if (error instanceof ReferenceError) {
console.error('Reference error occurred:', error.message);
} else {
console.error('An error occurred:', error.message);
}
}
6.1.2. Throwing Custom Errors
6.1.2.1. Creating and Throwing Custom Error Objects:
You can create custom error objects using the Error constructor or by extending the Error class.
Custom error objects allow you to provide more specific information about the error.
Example of creating and throwing a custom error:
function divide(a, b) {
if (b === 0) {
throw new Error('Division by zero is not allowed.');
}
return a / b;
}
try {
const result = divide(10, 0);
console.log('Result:', result);
} catch (error) {
console.error('An error occurred:', error.message);
}
6.1.2.2. Error Handling Best Practices:
Handle errors gracefully to prevent your code from crashing.
Use custom error objects to provide meaningful error messages.
Use descriptive error messages that help in debugging.
Log errors for debugging purposes but avoid exposing sensitive information.
6.2. Debugging Techniques
6.2.1. Console.log and Debugging Tools
6.2.1.1. Using console.log for Debugging:
console.log() is a powerful tool for debugging JavaScript code.
It allows you to print values, messages, and other information to the browser's console.
Example of using console.log() for debugging:
const name = 'John';
console.log('Name:', name);
const numbers = [1, 2, 3, 4, 5];
console.log('Numbers:', numbers);
6.2.1.2. Inspecting Variables and Objects:
You can inspect variables and objects in the console by logging them using console.log().
Objects can be expanded to view their properties and values.
Example of inspecting variables and objects:
const person = {
name: 'Alice',
age: 30,
city: 'New York',
};
console.log('Person object:', person);
6.2.2. Using Breakpoints
6.2.2.1. Setting Breakpoints in Browser Developer Tools:
Browser developer tools provide a powerful debugging environment.
You can set breakpoints in your code to pause execution at specific lines.
Example of setting a breakpoint in Chrome DevTools:
Open Chrome DevTools (usually by pressing F12 or right-clicking and selecting "Inspect").
Go to the "Sources" tab.
Navigate to the JavaScript file you want to debug.
Click on the line number where you want to set a breakpoint. A blue marker will appear.
6.2.2.2. Stepping Through Code Execution:
Once a breakpoint is set, you can use debugging controls to step through code execution.
Common controls include "Step Into," "Step Over," and "Step Out."
Example of stepping through code execution:
Set a breakpoint at the desired line.
Refresh the page or trigger the code that reaches the breakpoint.
Use debugging controls to step through the code one line at a time.
7.1. Closures and Scope
7.1.1. Lexical Scope
7.1.1.1. Understanding Variable Scope:
Variable scope in JavaScript determines where a variable is accessible within your code.
JavaScript uses lexical (or static) scoping, which means that variable scope is determined by the
placement of variables within the code.
Example of variable scope:
function outerFunction() {
const outerVar = 'I am from outerFunction';

function innerFunction() {
const innerVar = 'I am from innerFunction';
console.log(outerVar); // Accessible
}

innerFunction();
console.log(innerVar); // Not accessible
}
outerFunction();
7.1.1.2. Scope Chain and Closures:
In JavaScript, each function creates its own scope.
A closure is a function that "closes over" its lexical scope, preserving access to variables even
after the outer function has finished executing.
Example of a closure:
function outerFunction() {
const outerVar = 'I am from outerFunction';
function innerFunction() {
console.log(outerVar); // Accessible due to closure
}
return innerFunction;
}
const closureFunction = outerFunction();
closureFunction(); // Still has access to outerVar
7.1.2. Closure Use Cases
7.1.2.1. Private Variables and Functions:
Closures are commonly used to create private variables and functions.
These variables and functions are inaccessible from outside the closure, providing data
encapsulation.
Example of private variables using closures:
function createCounter() {
let count = 0;
return function() {
count++;
console.log(count);
};
}
const counter = createCounter();
counter(); // 1
counter(); // 2
7.1.2.2. Callback Functions and Asynchronous Code:
Callback functions often rely on closures to maintain access to the surrounding context.
They are widely used in asynchronous programming to handle tasks like AJAX requests and
timers.
Example of a callback function with a closure:
function fetchData(url, callback) {
// Simulate an asynchronous request
setTimeout(function() {
const data = 'Some data from the server';
callback(data);
}, 1000);
}
fetchData('https://api.example.com/data', function(result) {
console.log('Data received:', result);
});
7.2. Prototypes and Inheritance
7.2.1. Prototype Chain
7.2.1.1. Prototype Inheritance Model:
JavaScript uses a prototype-based inheritance model where objects inherit properties and
methods from their prototypes.
Objects in JavaScript have a hidden [[Prototype]] property that points to their prototype object.
Example of prototype inheritance:
// Define a prototype object
const animal = {
speak() {
console.log('Animal speaks');
}
};
// Create an object that inherits from the prototype
const dog = Object.create(animal);
// The dog object inherits the speak method from its prototype
dog.speak(); // Outputs: "Animal speaks"
7.2.1.2. The Prototype Property:
Constructor functions in JavaScript have a prototype property that is used to define shared
properties and methods for objects created by that constructor.
Instances created from a constructor function inherit from this prototype.
Example of using the prototype property:
// Define a constructor function
function Person(name) {
this.name = name;
}
// Add a method to the prototype
Person.prototype.greet = function() {
console.log(`Hello, my name is ${this.name}`);
};
// Create instances of Person
const person1 = new Person('Alice');
const person2 = new Person('Bob');
person1.greet(); // Outputs: "Hello, my name is Alice"
person2.greet(); // Outputs: "Hello, my name is Bob"
7.2.2. Object-Oriented Programming in JavaScript
7.2.2.1. Creating Constructor Functions:
Constructor functions are used to create objects with shared properties and methods.
They are typically named with an initial capital letter.
Example of creating a constructor function:
function Car(make, model) {
this.make = make;
this.model = model;
}
// Create instances of Car
const car1 = new Car('Toyota', 'Camry');
const car2 = new Car('Honda', 'Civic');
7.2.2.2. Extending Objects with Prototypes:
You can extend constructor function prototypes to add shared methods.
Example of extending a constructor function prototype:
function Dog(name) {
this.name = name;
}
// Add a method to the Dog prototype
Dog.prototype.bark = function() {
console.log(`${this.name} barks`);
};
const dog1 = new Dog('Buddy');
dog1.bark(); // Outputs: "Buddy barks"
7.3. ES6+ Features
7.3.1. Arrow Functions
7.3.1.1. Simplifying Function Syntax:
Arrow functions are a concise way to write functions in JavaScript.
They provide a shorter syntax for defining functions compared to traditional function
expressions.
Example of an arrow function:
// Traditional function expression
const add = function(a, b) {
return a + b;
};
// Arrow function
const add = (a, b) => a + b;
7.3.1.2. Lexical this Binding:
Arrow functions have a lexical this binding, which means they capture the this value from the
surrounding context.
They are often used to avoid the common issue of losing the this context in callback functions.
Example of lexical this binding with arrow functions:
function Counter() {
this.count = 0;
setInterval(() => {
// "this" refers to the Counter instance
this.count++;
console.log(this.count);
}, 1000);
}
const counter = new Counter();
7.3.2. Template Literals
7.3.2.1. Interpolating Variables in Strings:
Template literals allow you to embed variables directly in string literals using ${} syntax.
This provides a more readable and convenient way to create strings with variable values.
Example of interpolating variables in strings with template literals:
const name = 'Alice';
const age = 30;
const message = `Hello, my name is ${name} and I am ${age} years old.`;
console.log(message); // Outputs: "Hello, my name is Alice and I am 30 years old."
7.3.2.2. Multi-line Strings:
Template literals also support multi-line strings without the need for escape characters like \n.
You can simply include line breaks within the template.
Example of multi-line strings with template literals:
const multiline = `
This is a
multi-line
string.
`;
console.log(multiline);
// Outputs:
// "This is a
// multi-line
// string."
7.3.3. Destructuring
7.3.3.1. Extracting Values from Objects and Arrays:
Destructuring is a feature in ES6+ that allows you to extract values from objects and arrays
easily.
It provides a concise way to assign variables to specific properties or elements.
Destructuring Objects:
const person = { firstName: 'Alice', lastName: 'Johnson' };
// Extract values from an object
const { firstName, lastName } = person;
console.log(firstName); // Outputs: "Alice"
console.log(lastName); // Outputs: "Johnson"
Destructuring Arrays:
const numbers = [1, 2, 3];
// Extract values from an array
const [first, second, third] = numbers;
console.log(first); // Outputs: 1
console.log(second); // Outputs: 2
console.log(third); // Outputs: 3
7.3.3.2. Default Values and Renaming Variables:
Destructuring allows you to set default values for variables if the extracted value is undefined.
You can also rename variables during destructuring.
Default Values:
const person = { firstName: 'Alice' };
// Setting default value if lastName is undefined
const { firstName, lastName = 'Unknown' } = person;
console.log(firstName); // Outputs: "Alice"
console.log(lastName); // Outputs: "Unknown"
Variable Renaming:
const person = { first: 'Alice', last: 'Johnson' };
// Renaming variables during destructuring
const { first: firstName, last: lastName } = person;
console.log(firstName); // Outputs: "Alice"
console.log(lastName); // Outputs: "Johnson"
7.3.4. Classes and Modules
7.3.4.1. Creating Classes and Constructors:
Classes in JavaScript provide a way to create objects with shared properties and methods.
Constructors are special methods inside classes used to initialize object instances.
Creating a Class and Constructor:
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, my name is ${this.name}`);
}
}
const person = new Person('Alice', 30);
person.greet(); // Outputs: "Hello, my name is Alice"
7.3.4.2. Importing and Exporting Modules:
Modules in JavaScript allow you to split code into separate files and reuse it.
You can export functions, variables, or classes from one module and import them into another.
Exporting from a Module:
// math.js module
export function add(a, b) {
return a + b;
}
export const pi = 3.14159265;
Importing into Another Module:
// main.js module
import { add, pi } from './math.js';
console.log(add(2, 3)); // Outputs: 5
console.log(pi); // Outputs: 3.14159265
8.1. Consuming APIs
8.1.1. Fetching Data from External APIs
8.1.1.1. Making GET and POST Requests:
In web development, APIs (Application Programming Interfaces) are used to interact with
external services and fetch data.
The fetch() function in JavaScript is commonly used to make HTTP requests to external APIs.
Making a GET Request:
// Making a GET request to an external API
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
// Handle the fetched data
console.log(data);
})
.catch(error => {
console.error('Fetch error:', error);
});
Making a POST Request:
// Making a POST request with data
const dataToSend = { username: 'user123', password: 'password123' };
fetch('https://api.example.com/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(dataToSend),
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
// Handle the response
console.log(data);
})
.catch(error => {
console.error('Fetch error:', error);
});
8.1.1.2. Handling Asynchronous Responses:
Fetching data from external APIs is an asynchronous operation.
Promises and .then() are used to handle asynchronous responses from API requests.
8.1.2. Handling JSON Data
8.1.2.1. Parsing JSON Responses:
Many APIs return data in JSON (JavaScript Object Notation) format.
JavaScript provides JSON.parse() to convert JSON strings into JavaScript objects.
Parsing JSON Data:
const jsonResponse = '{"name": "Alice", "age": 30}';
const parsedData = JSON.parse(jsonResponse);
console.log(parsedData.name); // Outputs: "Alice"
console.log(parsedData.age); // Outputs: 30
8.1.2.2. Serializing JavaScript Objects to JSON:
To send data to an API, JavaScript objects can be converted into JSON strings using
JSON.stringify().
Serializing JavaScript Objects to JSON:
const userData = { name: 'Bob', age: 25 };
const jsonString = JSON.stringify(userData);
console.log(jsonString); // Outputs: '{"name":"Bob","age":25}'
Consuming APIs is a fundamental part of modern web development. The fetch() function
simplifies making GET and POST requests to external services. Handling asynchronous
responses with Promises allows you to manage data retrieval effectively. JSON is a widely used
data format for APIs, and JavaScript provides JSON.parse() and JSON.stringify() methods for
working with JSON data.
8.2. Popular JavaScript Libraries
8.2.1. Introduction to jQuery
8.2.1.1. Selecting and Manipulating DOM Elements with jQuery:
jQuery is a popular JavaScript library that simplifies DOM manipulation and event handling.
It provides a concise and easy-to-use syntax for selecting and modifying DOM elements.
Selecting DOM Elements:
// Using jQuery to select elements
const $element = $('.class-selector'); // By class
const $element2 = $('#id-selector'); // By ID
const $element3 = $('tag-selector'); // By tag name
// Manipulating DOM elements
$element.text('New text content');
$element.addClass('new-class');
$element.css('color', 'red');
8.2.1.2. Event Handling and Animations:
jQuery simplifies event handling with methods like .click(), .hover(), etc.
It also provides animation functions for creating smooth transitions and effects.
Event Handling:
// Handling a click event
$element.click(function() {
alert('Button clicked!');
});
// Event delegation
$('ul').on('click', 'li', function() {
alert('List item clicked!');
});
// Animations
$element.fadeOut(1000);
$element.fadeIn(1000);
$element.slideUp(1000);
$element.slideDown(1000);
8.2.2. Working with React or Vue.js (Choose One)
8.2.2.1. Building User Interfaces with Components:
React and Vue.js are popular JavaScript libraries/frameworks for building user interfaces (UIs)
using a component-based architecture.
Components are reusable, self-contained UI elements.
React Example:
// Creating a React component
class Greeting extends React.Component {
render() {
return <div>Hello, {this.props.name}!</div>;
}
}
// Rendering the component
ReactDOM.render(<Greeting name="Alice" />, document.getElementById('root'));
Vue.js Example:
// Creating a Vue.js component
Vue.component('greeting', {
props: ['name'],
template: '<div>Hello, {{ name }}!</div>'
});
// Creating a Vue instance
new Vue({
el: '#app',
data: {
userName: 'Bob'
}
});
8.2.2.2. State Management and Routing:
Both React and Vue.js offer tools for managing application state and handling routing.
State Management (Redux in React):
// Redux store setup
import { createStore } from 'redux';
import rootReducer from './reducers';
const store = createStore(rootReducer);
// Accessing state
const currentState = store.getState();
// Dispatching actions
store.dispatch({ type: 'INCREMENT' });
store.dispatch({ type: 'DECREMENT' });
Routing (Vue Router in Vue.js):
// Vue Router setup
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: About },
// Define more routes
];
const router = new VueRouter({
routes
});
// Navigate to a route
router.push('/about');
jQuery simplifies DOM manipulation and event handling, making it suitable for smaller
projects and simple interactions. React and Vue.js, on the other hand, offer more robust
solutions for building complex user interfaces with reusable components. They also provide
tools for managing application state and handling routing, making them ideal for larger and
more interactive web applications.

You might also like