Tuesday, October 8, 2024

JAVASCRIPT (JS)


 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 a if 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 with const 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

5 == 3 (false)

!=

Not equal to

10 != 20 (true)

===

Strictly equal to (both value and type)

'5' === 5 (false)

!==

Strictly not equal to

'5' !== 5 (true)

< 

Less than

3 < 5 (true)

> 

Greater than

10 > 7 (true)

<=

Less than or equal to

5 <= 5 (true)

>=

Greater than or equal to

12 >= 10 (true)

Export to Sheets

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, and reduce, 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 name is 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

  1. Parsing: The JavaScript engine parses the code, breaking it down into tokens and analyzing its syntax.
  2. Hoisting: Variable and function declarations are hoisted to the top of their scope.
  3. Creation Phase: Variables and functions are initialized with their default values (undefined for variables and the function object itself).
  4. 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 with undefined.
  • 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 and const 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) using let or const.

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

Difference Between List and Array in Python

  Follow me 📝 What is a List in Python? A list in Python is a built-in data structure that lets you store a collection of items in a sin...