JavaScript
Introduction
to JavaScript
JavaScript
It
is a versatile programming language that plays a crucial role in creating
interactive and dynamic web pages. It's one of the core technologies of the
web, alongside HTML (for structure) and CSS (for styling).
Key characteristics of JavaScript:
- Scripting
Language:
It's designed to be embedded within HTML documents, allowing for
client-side programming.
- Object-Oriented:
JavaScript follows an object-oriented paradigm, where data and behavior
are encapsulated in objects.
- Dynamic
Typing:
Variables in JavaScript don't require explicit declaration of their data
type.
- Event-Driven:
JavaScript is often used to handle events triggered by user interactions
(like clicks, key presses, etc.), making web pages more responsive.
- Cross-Platform:
JavaScript code can run in any web browser, regardless of the operating
system.
Common use cases of JavaScript:
- Web
Development:
Creating interactive web pages, animations, and dynamic content.
- Server-Side
Development:
Node.js allows JavaScript to be used for server-side programming.
- Mobile
App Development:
Frameworks like React Native and Ionic use JavaScript to build mobile
apps.
- Game
Development:
JavaScript can be used to create web-based games.
Basic JavaScript Structure:
Syntax:
JavaScript
<script>
// Your JavaScript code here
</script>
Example:
JavaScript
<script>
alert ("Hello, world!");
</script>
This
code will display an alert box with the message "Hello, world!" when
the web page loads.
JavaScript
variables
are containers that store data values. They are used to hold different types of
information, such as numbers, strings, booleans, objects, and more.
Essentially, a variable is like a box where you can place and retrieve data.
Key points about JavaScript variables:
- Declaration:
Variables are declared using the var,
let,
or const
keywords.
- Data
Types:
Variables can hold various data types, including numbers, strings, booleans,
objects, arrays, undefined, and null.
- Assignment:
You assign values to variables using the assignment operator (=).
- Scope:
Variables have a scope that determines where they can be accessed (global
or local).
- Type
Coercion:
JavaScript is dynamically typed, which means the data type of a variable
can change during runtime.
Example:
JavaScript
let
name = "Alice"; // Declaring a variable named "name" and
assigning
const
age = 30; // Declaring a constant variable named "age" and assign
var
isStudent = true; // Declaring a variable named "isStudent" and ass
var,
let, and const: A Comparison
In JavaScript, var
, let
, and const
are keywords used to
declare variables. While they serve a similar purpose, there are significant
differences in their behavior and scope.
var
- Scope: Variables declared
with
var
have function scope or global scope. If declared within a function, they are only accessible within that function. If declared outside a function, they are accessible throughout the entire script. - Redeclaration: Variables declared
with
var
can be redeclared within the same scope. - Hoisting:
var
declarations are hoisted to the top of their scope, meaning they can be used before they are declared.
Example:
JavaScript
function myFunction() {
var x =
10;
console.log(x);
// Output: 10
if (
true) {
var y =
20;
console.log(y);
// Output: 20
}
console.log(y);
// Output: 20 (due to hoisting)
}
let
- Scope: Variables declared
with
let
have block scope. They are only accessible within the block where they are declared (e.g., within aif
statement,for
loop, or function). - Redeclaration: Variables declared
with
let
cannot be redeclared within the same scope. - Hoisting:
let
declarations are also hoisted, but they are in a "temporal dead zone" until they are initialized. This means you cannot use them before they are declared.
Example:
JavaScript
function myFunction() {
let x =
10;
console.log(x);
// Output: 10
if (
true) {
let y =
20;
console.log(y);
// Output: 20
}
console.log(y);
// Error: y is not defined (due to block scope)
}
const
- Scope: Similar to
let
, variables declared withconst
have block scope. - Redeclaration: Variables declared
with
const
cannot be redeclared within the same scope. - Reassignment: Once a variable is
declared with
const
, its value cannot be changed.
Example:
JavaScript
const PI =
3.14159;
console.log(PI);
// Output: 3.14159
PI =
3.15;
// Error: Cannot assign to constant variable
In
summary:
var
is generally avoided in m odern JavaScript due to its potential for unexpected behavior.let
is the preferred way to declare variables that need to be reassigned within a scope.const
is used for variables that should not be modified after their initial assignment.
Data
Types in JavaScript
JavaScript is a
dynamically typed language, meaning the data type of a variable is determined
at runtime based on its value. Here are the primary data types in JavaScript:
Primitive Data Types
- Number: Represents
numerical values, including integers and floating-point numbers.
JavaScript
let age =
25;
// Integer
let pi =
3.14159;
// Floating-point number
- String: Represents
sequences of characters enclosed in quotes.
JavaScript
let name =
"Alice";
let message =
'Hello, world!';
- Boolean: Represents true or
false values.
JavaScript
let isStudent =
true;
let isSunny =
false;
- Undefined: Represents a
variable that has been declared but not yet assigned a value.
JavaScript
let x;
// x is undefined
- Null: Represents an
empty value or the absence of a value.
JavaScript
let y =
null;
- Symbol: Represents a
unique identifier.
JavaScript
let uniqueSymbol =
Symbol(
'unique');
Object Data Type
- Object: Represents a
collection of key-value pairs.
JavaScript
let person = {
name:
"Bob",
age:
30,
city:
"New York"
};
Array Data Type
- Array: Represents an
ordered collection of values.
JavaScript
let numbers = [
1,
2,
3,
4,
5];
let fruits = [
"apple",
"banana",
"orange"];
Note: JavaScript also has
some special data types like BigInt
for larger integers and
Date
for representing dates
and times. However, these are less commonly used.
Concatenation
and Template Literals in JavaScript
Concatenation
Concatenation
is the process of combining multiple strings into a single string. In
JavaScript, you can concatenate strings using the +
operator.
Example:
JavaScript
let firstName = "John";
let lastName = "Doe";
let fullName = firstName + " " + lastName;
console.log(fullName); // Output: John Doe
Template Literals
Template
literals provide a more convenient way to create strings, especially when you
need to embed variables or expressions within them. They are enclosed in
backticks () and use ${}
to insert values.
Example:
JavaScript
let name =
"Alice";
let age =
30;
let message =
`Hello, ${name}! You are ${age} years old.`;
console.log(message);
// Output: Hello, Alice! You are 30 years old.
Key advantages of template literals:
- Easier to read: They are more
readable and maintainable compared to concatenation.
- Multi-line strings: You can write
multi-line strings without using escape sequences.
- Embedded expressions: You can directly
embed expressions within the template literal.
Example
of multi-line strings:
JavaScript
let poem =
`Roses are red,
Violets are blue,
Sugar is sweet,
And so are you.`;
console.log(poem);
Example
of embedded expressions:
JavaScript
let x =
10;
let y =
5;
let result =
`The sum of ${x} and ${y} is ${x + y}.`;
console.log(result);
In conclusion,
template literals offer a cleaner and more flexible way to create strings in
JavaScript, especially when you need to include variables or expressions within
them.
Arithmetic
Operators in JavaScript
Arithmetic
operators are used to perform mathematical operations on numbers. Here are the
common arithmetic operators in JavaScript:
Addition (+
)
Adds two
numbers.
JavaScript
let result =
5 +
3;
console.log(result);
// Output: 8
Subtraction (-
)
Subtracts the
second number from the first.
JavaScript
let difference =
10 -
4;
console.log(difference);
// Output: 6
Multiplication (*
)
Multiplies two
numbers.
JavaScript
let product =
2 *
6;
console.log(product);
// Output: 12
Division (/
)
Divides the
first number by the second.
JavaScript
let quotient =
20 /
5;
console.log(quotient);
// Output: 4
Modulus (%
)
Returns the
remainder of the division.
JavaScript
let remainder =
17 %
3;
console.log(remainder);
// Output: 2
Increment (++
)
Increases the
value of a number by 1.
JavaScript
let x =
5;
x++;
console.log(x);
// Output: 6
Decrement (--
)
Decreases the
value of a number by 1.
JavaScript
let y =
10;
y--;
console.log(y);
// Output: 9
Note: These operators can
also be used with variables or expressions. For example:
JavaScript
let a =
10;
let b =
5;
let result = a + b *
2;
// Evaluates to 20 (multiplication takes precedence)
Comparison
Operators
Comparison
operators are used to compare values and return a Boolean result (true or
false).
List of Operators
Operator |
Meaning |
Example |
== |
Equal
to |
|
!= |
Not
equal to |
|
=== |
Strictly
equal to (both value and type) |
|
!== |
Strictly
not equal to |
|
< |
Less
than |
|
> |
Greater
than |
|
<= |
Less
than or equal to |
|
>= |
Greater
than or equal to |
|
Example:
JavaScript
let x =
10;
let y =
5;
if (x > y) {
console.log(
"x is greater than y");
}
else {
console.log(
"x is less than or equal to y");
}
Conditional Statements
Conditional
statements allow you to execute different code blocks based on certain
conditions.
if
statement: Executes code if a condition is true.else
statement: Executes code if the condition is false.else if
statement: Checks additional conditions.
Example:
JavaScript
let age =
25;
if (age >=
18) {
console.log(
"You are an adult.");
}
else {
console.log(
"You are a minor.");
}
Nested Conditional Statement
You can nest
conditional statements within each other to create more complex logic.
Example:
JavaScript
let grade =
85;
if (grade >=
90) {
console.log(
"Excellent");
}
else
if (grade >=
80) {
console.log(
"Good");
}
else
if (grade >=
70) {
console.log(
"Average");
}
else {
console.log(
"Needs improvement");
}
Ternary Operator - Part 1
The ternary
operator provides a concise way to write conditional expressions.
Syntax:
JavaScript
condition ? expression1 : expression2
Example:
JavaScript
let isAdult = age >=
18 ?
true :
false;
Ternary Operator - Part 2
You can nest
ternary operators for more complex conditions.
Example:
JavaScript
let message = age >=
18 ?
"You are an adult" : age >=
13 ?
"You are a teenager" :
"You are a child";
Logical Operators Part 1
Logical
operators are used to combine multiple conditions.
&&
(AND): Returns true if both operands are true.||
(OR): Returns true if at least one operand is true.!
(NOT): Reverses the logical value.
Example:
JavaScript
let isStudent =
true;
let hasPassed =
true;
if (isStudent && hasPassed) {
console.log(
"You can graduate.");
}
Conditional Statement Exercise
Create a
program that determines whether a number is positive, negative, or zero.
Logical Operator Part 2
Explore more
use cases of logical operators, such as checking multiple conditions in a
single if
statement.
Logical Operator Part 3
Learn about
short-circuiting and operator precedence.
Nullish Coalescing
The nullish
coalescing operator (??
) returns the right-hand side operand if
the left-hand side is null or undefined.
Example:
JavaScript
let name =
"Alice";
let greeting = name ??
"Hello, stranger!";
Exercise - For Loop
Write a program
to print numbers from 1 to 10 using a for
loop.
Nested - for Loop
Use nested for
loops to create
patterns or iterate over multiple dimensions.
Example:
JavaScript
for (
let i =
0; i <
3; i++) {
for (
let j =
0; j <
4; j++) {
console.log(
"i:", i,
"j:", j);
}
}
Loops - for loop
The for
loop is a control flow
statement that repeatedly executes a block of code until a specified condition
becomes false.
Syntax:
JavaScript
for (initialization; condition; increment/decrement) {
// Code to be executed
}
Loops - while loop
The while
loop is another control
flow statement that repeatedly executes a block of code as long as a specified
condition is true.
Syntax:
JavaScript
while (condition) {
// Code to be executed
}
Exercise - While Loop
Write a program
to calculate the factorial of a number using a while
loop.
Error Handling - try and catch
Use try
and catch
blocks to handle
exceptions and prevent program crashes.
Example:
JavaScript
try {
let result =
10 /
0;
console.log(result);
}
catch (error) {
console.log(
"An error occurred:", error.message);
}
Functional
Programming in JavaScript: Functions
Function declaration
A function
declaration is a named function defined using the function
keyword. It can be
declared anywhere in the scope and can be called before or after its
declaration.
Example:
JavaScript
function greet(name) {
console.log(
"Hello, " + name +
"!");
}
greet(
"Alice");
// Output: Hello, Alice!
Anonymous Function & Function Expression
An anonymous
function is a function without a name. It's often used as a function
expression, where it's assigned to a variable.
Example:
JavaScript
const greet =
function(name) {
console.log(
"Hello, " + name +
"!");
};
greet(
"Bob");
// Output: Hello, Bob!
Return and undefined
The return
keyword is used to
specify the value that a function should return. If a function doesn't have a return
statement, it
implicitly returns undefined
.
Example:
JavaScript
function add(a, b) {
return a + b;
}
let result = add(
3,
5);
console.log(result);
// Output: 8
Arrow Function
Arrow functions
are a concise syntax for writing functions. They are often used for short
functions.
Example:
JavaScript
const greet =
(name) => {
console.log(
"Hello, " + name +
"!");
};
greet(
"Charlie");
// Output: Hello, Charlie!
Function Exercise
Write a
function that takes an array of numbers as input and returns the sum of all the
elements.
Solution:
JavaScript
function sumArray(arr) {
let sum =
0;
for (
let i =
0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
let numbers = [
1,
2,
3,
4,
5];
let result = sumArray(numbers);
console.log(result);
// Output: 15
Additional Notes:
- Functional
programming emphasizes the use of pure functions, which have no side
effects and always return the same output for the same
input.
- Higher-order
functions, such as
map
,filter
, andreduce
, are commonly used in functional programming to transform and manipulate data. - JavaScript also
supports closures, which allow functions to access variables from outer
scopes even after those scopes have been exited.
String
Methods in JavaScript
Iterating over String
You can iterate
over the characters of a string using a for
loop or the forEach()
method.
Example:
JavaScript
let str =
"Hello, world!";
// Using a for loop
for (
let i =
0; i < str.length; i++) {
console.log(str[i]);
}
// Using forEach()
str.split(
'').forEach(
char => {
console.log(char);
});
String Method - charAt & charCodeAt
- charAt(index):
Returns the character at the specified index.
- charCodeAt(index):
Returns the Unicode value of the character at the specified index.
Example:
JavaScript
let str =
"Hello";
console.log(str.charAt(
1));
// Output: e
console.log(str.charCodeAt(
0));
// Output: 72 (ASCII code for 'H')
String Method - indexOf
indexOf(searchValue, start)
: Returns the index of the first occurrence of the specified value within the string.
Example:
JavaScript
let str =
"Hello, world!";
console.log(str.indexOf(
'o'));
// Output: 4
console.log(str.indexOf(
'world',
6));
// Output: 7
String Method - includes
includes(searchValue, start)
: Returns true if the string contains the specified value.
Example:
JavaScript
let str =
"Hello, world!";
console.log(str.includes(
'world'));
// Output: true
console.log(str.includes(
'foo'));
// Output: false
String
Method - toUpperCase & toLowerCase
- toUpperCase():
Converts all characters in the string to uppercase.
- toLowerCase():
Converts all characters in the string to lowercase.
Example:
JavaScript
let str = "Hello, world!";
console.log(str.toUpperCase()); // Output: HELLO, WORLD!
console.log(str.toLowerCase()); // Output: hello, world!
String Method - substring
substring (start, end)
: Extracts a substring from the string.
Example:
JavaScript
let str =
"Hello, world!";
console.log (str.substring(
0,
5));
// Output: Hello
console.log(str.substring(
7));
// Output: world!
String Method - trim
trim ()
: Removes whitespace from the beginning and end of the string.
Example:
JavaScript
let str =
“ Hello, world! ”;
console.log(str.trim());
// Output: Hello, world!
Arrays
in JavaScript
Iterating Over Array
You can iterate
over the elements of an array using a for
loop, a for...of
loop, or the forEach()
method.
Example:
JavaScript
let fruits = [
"apple",
"banana",
"orange"];
// Using a for loop
for (
let i =
0; i < fruits.length; i++) {
console.log(fruits[i]);
}
// Using for...of loop
for (
let fruit
of fruits) {
console.log(fruit);
}
// Using forEach()
fruits.forEach(
fruit => {
console.log(fruit);
});
Copy By Reference
Arrays in
JavaScript are passed by reference. When you assign an array to another variable,
both variables point to the same underlying array. Modifying one array will
affect the other.
Example:
JavaScript
let fruits = [
"apple",
"banana"];
let fruitsCopy = fruits;
fruitsCopy.push(
"orange");
console.log(fruits);
// Output: ["apple", "banana", "orange"]
Array Method - Push & Concat
push()
: Adds elements to the end of an array.concat()
: Creates a new array by merging existing arrays.
Example:
JavaScript
let fruits = [
"apple",
"banana"];
fruits.push(
"orange");
console.log(fruits);
// Output: ["apple", "banana", "orange"]
let fruits2 = [
"grape",
"mango"];
let combinedFruits = fruits.concat(fruits2);
console.log(combinedFruits);
// Output: ["apple", "banana", "orange", "grape", "mango"]
Array Method - pop, splice
pop()
: Removes the last element from an array and returns it.splice(start, deleteCount, ...items)
: Removes elements from an array and optionally inserts new elements.
Example:
JavaScript
let fruits = ["apple", "banana", "orange"];
let removedFruit = fruits.pop();
console.log(removedFruit); // Output: orange
console.log(fruits); // Output: ["apple", "banana"]
fruits.splice(
1,
1,
"grape");
console.log(fruits);
// Output: ["apple", "grape", "orange"]
Array Method - includes
includes(searchValue, start)
: Returns true if the array contains the specified element.
Example:
JavaScript
let fruits = ["apple", "banana", "orange"];
console.log(fruits.includes("banana")); // Output: true
console.log(fruits.includes("grape")); // Output: false
Array Method - sort
sort()
: Sorts the elements of an array in place. By default, it sorts strings alphabetically and numbers numerically.
Example:
JavaScript
let numbers = [
3,
1,
4,
2];
numbers.sort();
console.log(numbers);
// Output: [1, 2, 3, 4]
split and join
split()
: Splits a string into an array of substrings.join()
: Joins the elements of an array into a string.
Example:
JavaScript
let str =
"Hello, world!";
let words = str.split(
' ');
console.log(words);
// Output: ["Hello,", "world!"]
let joinedStr = words.join(
'-');
console.log(joinedStr);
// Output: Hello,-world!
Spread Array
The spread
operator (...
) can be used to spread
the elements of an array into another array or function call.
Example:
JavaScript
let fruits = [
"apple",
"banana"];
let combinedFruits = [
"orange", ...fruits];
console.log(combinedFruits);
// Output: ["orange", "apple", "banana"]
Destructuring Array
Destructuring
allows you to extract elements from an array into individual variables.
Example:
JavaScript
let fruits = [
"apple",
"banana",
"orange"];
let [firstFruit, secondFruit] = fruits;
console.log(firstFruit);
// Output: apple
console.log(secondFruit);
// Output: banana
Objects
in JavaScript
Object
Properties
Objects in
JavaScript are collections of key-value pairs. The keys are called properties,
and the values can be of any data type.
Example:
JavaScript
let person = {
name:
"Alice",
age:
30,
city:
"New York"
};
Functions as Property
You can assign
functions as properties of objects. These functions are called methods.
Example:
JavaScript
let person = {
name:
"Alice",
age:
30,
greet:
function() {
console.log(
"Hello, my name is " +
this.name);
}
};
person.greet();
// Output: Hello, my name is Alice
Computed Properties
Computed
properties allow you to dynamically generate property names based on
expressions.
Example:
JavaScript
let key =
"age";
let person = {
[key]:
30
};
console.log(person.age);
// Output: 30
Property Shorthand
If a property
name is the same as a variable name, you can use property shorthand.
Example:
JavaScript
let name =
"Alice";
let age =
30;
let person = {
name,
age
};
for
in
The for...in
loop iterates over the
properties of an object.
Example:
JavaScript
let person = {
name:
"Alice",
age:
30,
city:
"New York"
};
for (
let property
in person) {
console.log(property, person[property]);
}
Object Reference & Shallow Copy
When you assign
an object to another variable, both variables point to the same object. To
create a copy of an object, you can use the Object.assign()
method or the spread
operator.
Example:
JavaScript
let person = {
name:
"Alice",
age:
30
};
let personCopy =
Object.assign({}, person);
// or let personCopy = { ...person };
personCopy.age =
31;
console.log(person.age);
// Output: 30 (original object is not modified)
Optional Chaining
The optional
chaining operator (?.
) provides a concise way
to access nested properties without throwing an error if a property is
undefined or null.
Example:
JavaScript
let user = {
address: {
street:
"123 Main St"
}
};
let streetName = user?.address?.street;
console.log(streetName);
// Output: 123 Main St
Destructuring Object
Destructuring
allows you to extract properties from an object into individual variables.
Example:
JavaScript
let person = {
name:
"Alice",
age:
30
};
let { name, age } = person;
console.log(name, age);
// Output: Alice 30
Keys, values & entries
Object.keys(obj)
: Returns an array of the object's keys.Object.values(obj)
: Returns an array of the object's values.Object.entries(obj)
: Returns an array of key-value pairs.
Example:
JavaScript
let person = {
name:
"Alice",
age:
30
};
let keys =
Object.keys(person);
let values =
Object.values(person);
let entries =
Object.entries(person);
console.log(keys);
// Output: ["name", "age"]
console.log(values);
// Output: ["Alice", 30]
console.log(entries);
// Output: [["name", "Alice"], ["age", 30]]
'this' keyword
The this
keyword refers to the
object that the function is associated with.
Example:
JavaScript
let person = {
name: "Alice",
greet: function() {
console.log("Hello, my name is " + this.name);
}
};
person.greet(); // Output: Hello, my nameis Alice
Function Borrowing - Call and Apply
You can call a
method on an object that it doesn't belong to using the call()
or apply()
methods.
Example:
JavaScript
let person1 = {
name:
"Alice"
};
let
person2 = {
name: "Bob"
};
function greet() {
console.log("Hello, my name is " + this.name);
}
greet.call(person1); // Output: Hello, my name is Alice
greet.apply(person2);
// Output: Hello, my name is Bob
Function Borrowing - Bind
The bind()
method creates a new
function that, when called, has this
set to a specified
value.
Example:
JavaScript
let person = {
name:
"Alice"
};
let greetAlice = greet.bind(person);
greetAlice();
// Output: Hello, my name is Alice
Constructor “new”
The new
keyword is used to
create new objects from a constructor function.
Example:
JavaScript
function Person(name, age) {
this.name = name;
this.age = age;
}
let person =
new Person(
"Alice",
30);
console.log(person.name);
// Output: Alice
'this' keyword - exercise
Create a Person
object with properties name
and age
. Add a method getAge()
that returns the
person's age.
How
JavaScript Works: Behind the Scenes
Execution Context
When a
JavaScript script is executed, an execution context is created. This context
holds information about the code that is currently running, including
variables, functions, and the scope chain.
How JS Executes Code
- Parsing: The JavaScript
engine parses the code, breaking it down into tokens and analyzing its
syntax.
- Hoisting: Variable and
function declarations are hoisted to the top of their scope.
- Creation Phase: Variables and
functions are initialized with their default values (undefined for
variables and the function object itself).
- Execution Phase: The code is
executed line by line, and values are assigned to variables.
Call Stack
The
call stack is a data structure that keeps track of the functions that are
currently being executed. When a function is called, it's pushed onto the
stack. When the function returns, it's popped off the stack.
Example:
JavaScript
function outer() {
console.log(
"Outer function");
inner();
}
function inner() {
console.log(
"Inner function");
}
outer();
The call stack
will look like this:
outer()
inner()
When inner()
returns, it's popped
off the stack, and the execution resumes in outer()
.
Hoisting - var & function
var
declarations: Hoisted to the top of their scope, initialized withundefined
.- Function declarations: Hoisted to the top
of their scope, creating a function object.
Example:
JavaScript
console.log(x);
// Output: undefined
var x =
10;
function greet() {
console.log(
"Hello!");
}
greet();
// Output: Hello!
Hoisting - let, const and TDZ
let
andconst
declarations: Hoisted to the top of their scope, but in a "temporal dead zone" (TDZ) until they are initialized. This means you cannot use them before they are declared.
Example:
JavaScript
console.log(y);
// Error: Cannot access 'y' before initialization
let y =
20;
Key
points to remember:
- JavaScript is a
single-threaded language, meaning only one piece of code can be executed
at a time.
- The call stack
plays a crucial role in managing function calls and returns.
- Hoisting can lead
to unexpected behavior if not understood properly.
- Understanding how
JavaScript works behind the scenes can help you write more efficient and maintainable
code.
More
About Functions in JavaScript
Pure Functions
A pure function
is a function that:
- Always returns the
same output for the same input.
- Has no side effects
(doesn't modify external variables or objects).
Example:
JavaScript
function add(a, b) {
return a + b;
}
let result = add(
3,
5);
console.log(result);
// Output: 8
First-Class Functions
In
JavaScript, functions are first-class citizens, meaning they can be:
- Assigned
to variables
- Passed
as arguments to other functions
- Returned from
functions
Example:
JavaScript
function greet(name) {
return
"Hello, " + name +
"!";
}
let greeting = greet(
"Alice");
console.log(greeting);
// Output: Hello, Alice!
Higher-Order
Functions
Higher-order
functions are functions that take other functions as arguments or return
functions as
results.
Example:
JavaScript
function applyOperation(a, b, operation) {
return operation(a, b);
}
function add(a, b) {
return a + b;
}
let result = applyOperation(
3,
5, add);
console.log(result);
// Output: 8
Map, Filter, Reduce
map()
: Creates a new array by applying a function to each element of the original array.filter()
: Creates a new array containing elements from the original array that pass a test.reduce()
: Applies a function to each element of an array and accumulates a single value.
Example:
JavaScript
let numbers = [
1,
2,
3,
4,
5];
let doubledNumbers = numbers.map(
x => x *
2);
console.log(doubledNumbers);
// Output: [2, 4, 6, 8, 10]
let evenNumbers = numbers.filter(
x => x %
2 ===
0);
console.log(evenNumbers);
// Output: [2, 4]
let sum = numbers.reduce(
(acc, curr) => acc + curr,
0);
console.log(sum);
// Output: 15
Argument Object
The arguments
object is an array-like
object that contains the arguments passed to a function.
Example:
JavaScript
function sum() {
let total = 0;
for (let i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}
let result = sum(1, 2, 3, 4, 5);
console.log(result); // Output: 15
Rest Parameter
The rest
parameter (...
) allows you to collect
multiple arguments into an array.
Example:
JavaScript
function sum(...numbers) {
let total =
0;
for (
let num
of numbers) {
total += num;
}
return total;
}
let result = sum(
1,
2,
3,
4,
5);
console.log(result);
// Output: 15
Variable Scope - Global, Local and Block Scope
- Global scope: Variables declared
outside of any function or block.
- Local scope: Variables declared
within a function.
- Block scope: Variables declared
within a block (e.g.,
if
,for
,while
) usinglet
orconst
.
Scope and Scope Chain
The scope chain
determines the order in which variables are searched for when a variable is referenced.
The outer scope is searched if the variable is not found in the current scope.
Recursion
Recursion is a
technique where a function calls itself directly or indirectly.
Example:
JavaScript
function factorial(n) {
if (n ===
0) {
return
1;
}
else {
return n * factorial(n -
1);
}
}
let result = factorial(
5);
console.log(result);
// Output: 120
Closure
A closure is a
function that has access to variables from its outer scope, even after the
outer scope has finished executing.
Example:
JavaScript
function createCounter() {
let count = 0;
return function() {
count++;
return count;
};
}
let counter = createCounter();
console.log(counter()); // Output: 1
console.log(counter());
// Output: 2
DOM
(Document Object Model)
The DOM is a
programming interface that represents an HTML document as a tree structure. It
provides a way to interact with the elements of a webpage using JavaScript.
Example:
HTML
<!DOCTYPE html>
<html>
<head>
<title>DOM Example
</title>
</head>
<body>
<h1 id="myHeading">Hello, world!
</h1>
<p id="myParagraph">This is a paragraph.
</p>
</body>
</html>
In this
example, the DOM would represent the HTML document as a tree structure, with
the html
element as the root,
followed by the head
and body
elements, and then the h1
and p
elements.
Searching the DOM
You can use
JavaScript to access elements in the DOM by their ID, class name, or tag name.
Example:
JavaScript
let heading =
document.getElementById(
"myHeading");
let paragraph =
document.querySelector(
"p");
let paragraphs =
document.getElementsByTagName(
"p");
Event Listener Part 1
Event listeners
are used to handle events that occur on elements in the DOM.
Example:
JavaScript
let button =
document.getElementById(
"myButton");
button.addEventListener(
"click",
function() {
alert(
"Button clicked!");
});
Event Listener Part 2
You can attach
multiple event listeners to the same element.
Example:
JavaScript
button.addEventListener("mouseover", function() {
button.style.backgroundColor = "yellow";
});
button.addEventListener("mouseout", function() {
button.style.backgroundColor
=
"white";
});
Event Listener Part 3
You can prevent
the default behavior of an event using the preventDefault()
method.
Example:
JavaScript
let link =
document.getElementById(
"myLink");
link.addEventListener(
"click",
function(event) {
event.preventDefault();
alert(
"Link clicked!");
});
Bubbling & Capturing
Event bubbling
occurs when an event is triggered on a child element and propagates up through
its parent elements. Event capturing occurs when an event is triggered on a
parent element and propagates down through its child elements.
Example:
JavaScript
let outerDiv =
document.getElementById(
"outerDiv");
let innerDiv =
document.getElementById(
"innerDiv");
outerDiv.addEventListener(
"click",
function() {
console.log(
"Outer div clicked");
},
true);
// Capture phase
innerDiv.addEventListener(
"click",
function() {
console.log(
"Inner div clicked");
},
false);
// Bubble phase
Event Delegation
Event
delegation involves attaching an event listener to a parent element and
handling the event based on the target element. This can be more efficient than
attaching event listeners to individual child elements.
Example:
JavaScript
let list =
document.getElementById(
"myList");
list.
addEventListener("click", function(event) {
if (event.target.tagName === "LI") {
console.log("List item clicked:", event.target.textContent);
}
});
Creating HTML with Javascript
You can create
HTML elements dynamically using JavaScript.
Example:
JavaScript
let newParagraph = document.createElement("p");
newParagraph.textContent = "This is a new paragraph.";
document.body.appendChild(newParagraph);
Async and Defer
async
attribute: Tells the browser to download the script asynchronously and execute it as soon as it's available.defer
attribute: Tells the browser to download the script asynchronously but wait until the HTML has finished parsing before executing it.
Example:
HTML
<script src="script.js" async></script>
<script src="script2.js" defer></script>
Basics of Classes
Classes
In JavaScript, a class is a blueprint for creating objects. It defines the
properties and methods that objects of that class will have. Classes are
introduced in ES6 and provide a more structured approach to object-oriented
programming compared to using prototypes directly.
Example:
JavaScript
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, my name is ${this.name}.`);
}
}
const person1 = new Person("Alice",
30);
person1.greet();
// Output: Hello, my name is Alice.
Classes and Prototypes
While classes
provide a more concise syntax, they are ultimately built on top of prototypes.
The prototype
property of a class is
an object that contains the methods and properties that will be shared by all
instances of that class. When you access a property or
method on an object, JavaScript first checks if the property or method exists
on the object itself. If not, it checks the object's prototype. If still
not found, it checks the prototype's prototype, and so on until it reaches the
top of the prototype chain.
Example:
JavaScript
const person2 =
new Person(
"Bob",
25);
// Accessing a property on the instance
console.log(person2.name);
// Output: Bob
// Accessing a method on the prototype
console.log(person2.greet());
// Output: Hello, my name is Bob.
Class Inheritance
Inheritance
allows you to create new classes that inherit properties and methods from
existing classes. This promotes code reusability and modularity.
Example:
JavaScript
class Student extends Person {
constructor(name, age, grade) {
super(name, age);
this.grade = grade;
}
study() {
console.log(`${this.name} is studying
for class.`);
}
}
const student1 =
new Student(
"Charlie",
20,
12);
student1.greet();
// Output: Hello, my name is Charlie.
student1.study();
// Output: Charlie is studying for class.
Static Properties and Methods
Static
properties and methods belong to the class itself rather than its instances.
You can access them directly on the class name.
Example:
JavaScript
class MathUtils {
static PI =
3.14159;
static
calculateArea(radius) {
return MathUtils.PI * radius * radius;
}
}
console.log(MathUtils.PI);
// Output: 3.14159
console.log(MathUtils.calculateArea(
5));
// Output: 78.53975
Private Properties
Private
properties are accessible only within the class and its methods. In JavaScript,
there's no strict private property mechanism, but you can use a convention
known as the "underscore pattern" to indicate that a property is
intended to be private.
Example:
JavaScript
class Person {
constructor(name, age) {
this.name = name;
this._age = age;
// Private property
}
getAge() {
return
this._age;
}
}
const person3 =
new Person(
"David",
35);
console.log(person3.getAge());
// Output: 35
// console.log(person3. age); // Error: Property '_age' is not accessible
By
understanding these concepts and examples, you can effectively use classes to
create well-structured and maintainable JavaScript applications.
Polyfills
Polyfills are
pieces of code that provide functionality for features that may not be natively
supported in certain browsers or environments. They are essential for ensuring
compatibility and cross-browser functionality in web applications.
Polyfills for Map
The map()
method creates a new
array by applying a function to each element of an existing array.
Example:
JavaScript
if (!
Array.prototype.map) {
Array.prototype.map =
function(callback, thisArg) {
const newArray = [];
for (let i = 0; i < this.length; i++) {
newArray.push(callback.call(thisArg, this[i], i, this));
}
return newArray;
};
}
const
numbers = [
1,
2,
3,
4,
5];
const squaredNumbers = numbers.map(
x => x * x);
console.log(squaredNumbers);
// Output: [1, 4, 9, 16, 25]
Polyfills for Filter
The filter()
method creates a new
array containing elements from the original array that pass a test provided by
a function.
Example:
JavaScript
if (!
Array.prototype.filter) {
Array.prototype.filter =
function(callback, thisArg) {
const newArray = [];
for (
let i =
0; i <
this.length; i++) {
if (callback.call(thisArg,
this[i], i,
this)) {
newArray.push(
this[i]);
}
}
return newArray;
};
}
const numbers = [
1,
2,
3,
4,
5];
const evenNumbers = numbers.filter(
x => x %
2 ===
0);
console.log(evenNumbers);
// Output: [2, 4]
Polyfills for Reduce
The reduce()
method applies a
function to an accumulator and each element in an array to reduce it to a
single value.
Example:
JavaScript
if (!Array.prototype.reduce) {
Array.prototype.reduce = function(callback, initialValue) {
let accumulator = initialValue;
for (let i = 0; i < this.length;
i++) {
accumulator = callback(accumulator, this[i], i, this);
}
return accumulator;
};
}
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc,
cur) => acc + cur,
0);
console.log(sum);
// Output: 15
Polyfills for Flatten
The flatten()
method flattens an
array into a new array with sub-arrays removed.
Example:
JavaScript
if (!
Array.prototype.flatten) {
Array.prototype.flatten =
function() {
return
this.reduce(
(acc, cur) => acc.concat(
Array.isArray(cur) ? cur.flatten() : cur), []);
};
}
const nestedArray = [
1, [
2,
3], [
4, [
5,
6]]];
const flattenedArray = nestedArray.flatten();
console.log(flattenedArray);
// Output: [1, 2, 3, 4, 5, 6]
Polyfills for Call & Apply
The call()
and apply()
methods allow you to
invoke a function with a specified this
value and arguments.
Example:
JavaScript
if (!
Function.prototype.call) {
Function.prototype.call =
function(thisArg) {
const args =
Array.prototype.slice.call(
arguments,
1);
return
this.apply(thisArg, args);
};
}
if (!
Function.prototype.apply) {
Function.prototype.apply =
function(thisArg, args) {
const context = thisArg ||
window;
if (!args) {
args = [];
}
context.func =
this;
const result = context.func(...args);
delete context.func;
return result;
};
}
const person = {
name:
"Alice",
greet:
function() {
console.log(
`Hello, my name is ${this.name}.`);
}
};
const otherPerson = {
name:
"Bob"
};
person.greet.call(otherPerson);
// Output: Hello, my name is Bob.
Polyfills for Bind
The bind()
method creates a new
function that, when called, has a specified this
value and arguments.
Example:
``
No comments:
Post a Comment