Automation QA Testing Course Content

Javscript course content

JavaScript Course Content:

  • Introduction
  • Pre-requisites
  • Data Types
  • Strings
  • Operators
  • Variables
  • Arrays
  • Conditional statements (if, else, else if and Switch Statements)
  • Loops (For, While, For-in, For-of) 
  • Use Strict
  • Objects
  • Functions
  • Numbers
  • Booleans
  • Comparison and Logical Operators
  • Break and Continue
  • Iterables    
  • Sets and Set Methods
  • Maps
  • Classes and Inheritance
  • Static Methods
  • Callbacks
  • Asynchronous JavaScript
  • Promises
  • Async/Await
===================================================================

Introduction

History of JavaScript[1995]

  • JavaScript was created by Brendan Eich while working at Netscape Communications.
  • It was initially named Mocha, then LiveScript, and finally JavaScript (to capitalize on Java’s popularity).
  • JavaScript was designed in just 10 days and first appeared in Netscape Navigator 2.0.

Standardization - ECMAScript (1997)

  • Netscape submitted JavaScript to ECMA (European Computer Manufacturers Association) for standardization.

  •  It was standardized in 1997 by European Computer Manufacturers Association (ECMA) and officially known as ECMAScript.

  • In 1997, ECMAScript (ES1) was released as the official standard for JavaScript.

  • JavaScript versions


  • The latest version of JS is  4.30.0(March 21, 2025)
  • JavaScript is used for web, mobile (React Native), desktop (Electron), and even AI and IoT.

  • JavaScript started as a small scripting language but has evolved into one of the most powerful and widely used languages in the world.

JavaScript Reserved Words

In JavaScript you cannot use these reserved words as variables, labels, or function names:


Removed Reserved Words



JavaScript Comments

Not all JavaScript statements are "executed".

Code after double slashes // or between /* and */ is treated as a comment.

Comments are ignored, and will not be executed:

let x = 5;   // I will be executed

// x = 6;   I will NOT be executed

JavaScript Identifiers / Names

Identifiers are JavaScript names.

Identifiers are used to name variables and keywords, and functions.

The rules for legal names are the same in most programming languages.

A JavaScript name must begin with:

  • A letter (A-Z or a-z)
  • A dollar sign ($)
  • Or an underscore (_)

Subsequent characters may be letters, digits, underscores, or dollar signs.

Note

Numbers are not allowed as the first character in names.

This way JavaScript can easily distinguish identifiers from numbers.

JavaScript is Case Sensitive

All JavaScript identifiers are case sensitive

JavaScript Naming Conventions:

1. Class Names

  • Convention: PascalCase

  • Definition: Every word starts with a capital letter and no underscores or hyphens.

  • Purpose: Used to define blueprints for objects (like user profiles, orders, etc.).

  • Example

class UserProfile {

constructor(name) {

this.name = name;

}

}

2. Method Names

  • Convention: camelCase

  • Definition: Starts with a lowercase letter, each subsequent word starts with a capital letter.

  • Purpose: Represents actions or behaviors an object can perform.

Example

class Calculator {

addNumbers(a, b) {

return a + b;

}

}

3. Variable Names

  • Convention: camelCase

  • Definition: Similar to methods—starts with lowercase, capitalizes each new word.

  • Purpose: Used to store data values such as numbers, strings, or objects

Example

let userAge = 25;

const isLoggedIn = true;

4. File Names

  • Convention:

    • For regular modules/files: kebab-case

    • For React components: PascalCase.js

  • Definition:

    • kebab-case: all lowercase letters with hyphens separating words.

    • PascalCase: each word capitalized, no spaces or hyphens.

  • Purpose: Organizes source files; improves readability and maintainability.

  • Examples:

    • user-service.js (module)

    • UserProfile.js (React component)

    • dateUtils.js (utility module)

5. Constants

  • Convention: UPPER_SNAKE_CASE

  • Definition: All uppercase letters, words separated by underscores.

  • Purpose: Used for values that should never change (true constants).

Example

const MAX_USERS = 100;

6. Private Fields

  • Convention: #camelCase (ES2022+)

  • Definition: Prefix a field name with # to make it truly private inside a class.

  • Purpose: Used to restrict access to data within the class scope.

Example

class BankAccount {

#balance = 0;

deposit(amount) {

this.#balance += amount;

}

}


JavaScript Output [Display Possibilities]

JavaScript can "display" data in different ways:

  • Writing into an HTML element, using innerHTML or innerText.
  • Writing into the HTML output using document.write().
  • Writing into an alert box, using window.alert().
  • Writing into the browser console, using console.log().

==================================================

Pre-requisites

  • Download & Install Node JS
  • Visual Studio Code[VS Code]
Download & Install Node JS on Windows
  • Open Command Prompt (CMD) or PowerShell.
  • Type the following command and press Enter to check the Node.js version:
  • If installed correctly, you'll see the Node.js version (e.g., v18.17.1).

Step 1: Download Node.js

  • Open your web browser and type download node js.


  • Click on above highlighted link, then you will navigate to below page.
  • Click the LTS version (recommended) to start downloading the installer (.msi file).



Step 2: Run the Installer

  • Locate the downloaded .msi file (usually in the Downloads folder).



  • Double-click to run the installer.


Step 3: Follow the Installation Wizard

  • Click Next on the welcome screen.



  • Accept the license agreement and click Next.



  • Choose the installation location (default is fine) and click Next.



  • Ensure that "Node.js runtime" and "npm package manager" are selected, then click Next.



  • Click Install and wait for the process to complete.

  • Click on Finish.

Step 4: Verify the Installation

  1. Open Command Prompt (CMD) or PowerShell.

  2. Type the following command and press Enter to check the Node.js version:


    ✅ If installed correctly, you'll see the Node.js version (e.g., v18.17.1).

  3. To check the npm (Node Package Manager) version, type:


    ✅ This confirms that npm is installed along with Node.js.

Download Visual Studio Code

  • Open your web browser and type download visual studio code.


  • Click on the "Download for Windows" button.
  • The installer (.exe file) will start downloading automatically.


Step 2: Run the Installer

  • Locate the downloaded .exe file (usually in the Downloads folder).

  • Double-click the file to launch the installer.


Step 3: Follow the Installation Wizard

  1. Click Next on the welcome screen.

  2. Accept the license agreement and click Next.


    3.Choose the installation location (default is fine) and click Next.



4.Select "Add to PATH" (important for command-line usage).

5.Click Install, and wait for the installation to complete.


Step 4: Launch VS Code

1.Once installed, check "Launch Visual Studio Code" and click Finish.

2.VS Code will open. 🎉


Step 5: Verify Installation

  1. Open Command Prompt (CMD) or PowerShell.

  2. Type the following command and press Enter:



    ✅ If installed correctly, it will display the VS Code version.


=================================================

 JavaScript Data Types

In JavaScript, data types define the kind of values a variable can hold. JavaScript is a dynamically-typed language, meaning that the type of a variable can change at runtime. There are 8 fundamental data types in JavaScript, which can be categorized into primitive and non-primitive types.



1. Primitive Data Types



Primitive data types are the most basic types in JavaScript. These include:

  • string
  • number
  • bigint
  • boolean
  • undefined
  • symbol
  • null

These are called "primitive" because they are immutable (cannot be changed) and are passed by value.

string

A string is a sequence of characters enclosed in quotes (single, double, or backticks).

Example:

let name = "Alice";

let greeting = 'Hello, ' + name;  // String concatenation

console.log(greeting);  // Output: Hello, Alice


// Template literals (backticks)

let message = `Welcome, ${name}!`;  // String interpolation

console.log(message);  // Output: Welcome, Alice!


number

The number type in JavaScript represents both integer and floating-point values.

Example:

let age = 30;          // Integer

let price = 99.99;     // Floating point number

let hexValue = 0xFF;   // Hexadecimal (255 in decimal)

let binary = 0b1010;   // Binary (10 in decimal)

let octal = 0o12;      // Octal (10 in decimal)


console.log(age);      // 30

console.log(price);    // 99.99

console.log(hexValue); // 255

console.log(binary);   // 10

console.log(octal);    // 10

JavaScript uses floating-point arithmetic for all numbers, even integers. Be careful with precision when using very large or very small numbers.


bigint

The BigInt type can represent integers with arbitrary precision. It is used for large numbers beyond the safe integer limit for regular numbers.

Example:

let bigNumber = 1234567890123456789012345678901234567890n; // Adding 'n' to indicate BigInt
console.log(bigNumber);  // Output: 1234567890123456789012345678901234567890n
BigInt allows you to work with numbers larger than Number.MAX_SAFE_INTEGER (which is 2^53 - 1).

boolean

A boolean can only be one of two values: true or false. It is typically used in conditional statements.

Example:

let isActive = true;
let isCompleted = false;

if (isActive) {
  console.log("The task is active.");
} else {
  console.log("The task is not active.");
}
Booleans are commonly used for controlling flow in conditional statements like if, while, and for.

undefined

A variable that is declared but not assigned a value automatically has the value undefined. It is also the return value of functions that do not explicitly return anything.

Example:

let x;
console.log(x);  // Output: undefined

function example() {
  // No return statement
}
console.log(example());  // Output: undefined

null

The null type represents the intentional absence of any value. It is often used to indicate that a variable is empty or should hold an object later.

Example:

let user = null;
console.log(user);  // Output: null

if (user === null) {
  console.log("User is not defined.");
}

symbol

A symbol is a unique and immutable primitive value that can be used as the key for object properties. Each symbol is guaranteed to be unique.

A Symbol is a primitive data type introduced in ES6 (ES2015). It's created using the Symbol() function.

Example:

let sym1 = Symbol('description');
let sym2 = Symbol('description');
console.log(sym1 === sym2);  // Output: false, even though they have the same description

const obj = {};
obj[sym1] = 'Value of sym1';
console.log(obj[sym1]);  // Output: Value of sym1
Symbols are often used for creating unique keys in objects to avoid name clashes.

🔸 Why use Symbol?

Symbols are mainly used to:

  1. Avoid property name conflicts in objects.

  2. Create hidden (non-enumerable) properties.

  3. Implement internal object behaviors (e.g., with built-in symbols like Symbol.iterator).


🔹 Global Symbols: Symbol.for()

You can use Symbol.for() to create shared symbols that are registered globally.

Example:

let globalSym1 = Symbol.for("userId");

let globalSym2 = Symbol.for("userId");

console.log(globalSym1 === globalSym2); // true

Unlike Symbol(), Symbol.for() reuses the same symbol if the key already exists.


Here's a list of JavaScript data types along with what you get when you use the typeof operator on them:

🔹 Primitive Data Types



2.Non-Primitive Data Type (object)

An object is a non-primitive data type that can hold collections of key-value pairs. Unlike primitive types, objects are mutable and passed by reference.

Example:

let person = {
  name: 'Alice',
  age: 30,
  isActive: true
};

console.log(person.name);  // Output: Alice
console.log(person.age);   // Output: 30

person.age = 31;           // Modifying an object property
console.log(person.age);   // Output: 31

Objects are often used to represent real-world entities with properties and methods.

Array

An array is a special type of object used to store ordered collections of data. Arrays can hold values of different data types.

Example:

let numbers = [10, 20, 30, 40];
console.log(numbers[0]);  // Output: 10

let mixedArray = ['Hello', 100, true, null];
console.log(mixedArray[1]);  // Output: 100

Arrays have additional methods like push(), pop(), shift(), unshift(), and others to manipulate the collection.


🔹 Non-Primitive (Objects)

🧠 Quick Notes

  • typeof null is "object" — this is a known JavaScript bug from its early days.

  • typeof NaN is "number" — because NaN stands for "Not a Number" but still has type number.

  • Arrays and Dates return "object", so to check if something is an array, use Array.isArray(arr)


Quiz: JavaScript Data Types

1. What will be the output of the following code?

let a = 5;
let b = a;
b = 10;
console.log(a);
console.log(b);
  • a) 5, 10
  • b) 10, 10
  • c) 5, 5
  • d) 10, 5

Answer: a) 5, 10

Explanation: Since a is a primitive value (number), when b is assigned to a, b holds a copy of a. Changing b does not affect a.

2. What is the type of the following value?

let value = Symbol('description');
console.log(typeof value);
  • a) undefined
  • b) object
  • c) boolean
  • d) symbol

Answer: d) symbol

Explanation: The typeof operator returns symbol for values of the Symbol data type.

3. What will the following code output?
let obj = { a: 1, b: 2 };
let obj2 = obj;
obj2.a = 3;
console.log(obj.a);
  • a) 1
  • b) 2
  • c) 3
  • d) undefined

Answer: c) 3

Explanation: Since objects are passed by reference, modifying obj2 also modifies obj because they refer to the same object in memory.

4. What will the following code output?
let x = null;
console.log(x === undefined);
  • a) true
  • b) false
  • c) null
  • d) undefined

Answer: b) false

Explanation: null and undefined are distinct values in JavaScript, so x === undefined evaluates to

5. What is the result of the following?

let array = [1, 2, 3]; let newArray = array; newArray.push(4); console.log(array);
  • a) [1, 2, 3]
  • b) [1, 2, 3, 4]
  • c) [4, 1, 2, 3]
  • d) undefined

Answer: b) [1, 2, 3, 4]

Explanation: Since arrays are reference types, modifying new Array also modifies array because both point to the same array.


========================================================================

JavaScript Strings

  • Strings are for storing text
  • Strings are written with quotes
  • You can use single or double quotes:

Example

let carName1 = "Volvo XC60";  // Double quotes
let carName2 = 'Volvo XC60';  // Single quotes

Output

Volvo XC60 Volvo XC60


Quotes Inside Quotes

  • You can use quotes inside a string, as long as they don't match the quotes surrounding the string:

Example

let answer1 = "It's alright";
let answer2 = "He is called 'Johnny'";
let answer3 = 'He is called "Johnny"';

Output

It's alright
He is called 'Johnny'
He is called "Johnny"

Template Strings

  • Templates were introduced with ES6 (JavaScript 2016).
  • Templates are strings enclosed in backticks (`This is a template string`).
  • Templates allow single and double quotes inside a string:

Example

let text = `He's often called "Johnny"`;

Output

He's often called "Johnny"

Note

  • Templates are not supported in Internet Explorer.

Escape Characters

  • Because strings must be written within quotes, JavaScript will misunderstand this string:

Example

let text = "We are the so-called "Vikings" from the north.";

  • The string will be chopped to "We are the so-called ".
  • To solve this problem, you can use an backslash escape character.
  • The backslash escape character (\) turns special characters into string characters:

Example

  • \" inserts a double quote in a string:

let text = "We are the so-called \"Vikings\" from the north.";

Output

We are the so-called "Vikings" from the north.

------------------------------------------------

Example

  • \' inserts a single quote in a string:

let text= 'It\'s alright.';

Output

It's alright.

------------------------------------------------

Example

  • \\ inserts a backslash in a string:

let text = "The character \\ is called backslash.";

Output

The character \ is called backslash.

----------------------------------------------

  • Six other escape sequences are valid in JavaScript:

Note

  • The 6 escape characters above were originally designed to control typewriters, teletypes, and fax machines. They do not make any sense in HTML.


JavaScript Strings as Objects

  • Normally, JavaScript strings are primitive values, created from literals:

let x = "John";

  • But strings can also be defined as objects with the keyword new:

let y = new String("John");

  • Do not create String objects.
  • The new keyword complicates the code and slows down execution speed.
== (Double Equals) – Loose Comparison

  • Checks only values, not data types.
  • It converts (coerces) values if necessary before comparing.

Example 1

  • When using the == operator, x and y are equal:

let x = "John";

let y = new String("John");

console.log(x == y);

Output

true

Explanation:

  • x is a primitive string ("John").

  • y is a String object, created using new String("John").

When using the == (loose equality) operator, JavaScript performs type coercion. It converts the object (y) to a primitive for comparison.

------------------------------------------------

Example 2

  • When using the == operator, x and y are equal:
console.log(5 == "5"); // true (because "5" is converted to 5) console.log(true == 1); // true (because true is converted to 1)
=== (Triple Equals) – Strict Comparison

  • Checks both values and data types.
  • No type conversion happens.

Example 1

  • When using the  === operator, x and y are not equal:

let x = "John";

let y = new String("John");

console.log(x === y);

Output

false

Explanation:

  • x is a primitive string (typeof x === "string").
  • y is a String object (typeof y === "object").

The === operator checks for both value and type equality, and a primitive string is not strictly equal to a String object, even if they have the same content.

---------------------------------------------

Example 2

  • When using the === operator, x and y are not equal:
console.log(5 === "5"); // false (number vs. string) console.log(true === 1); // false (boolean vs. number)

----------------------------------------------

  • Comparing two JavaScript objects always returns false.

  • JavaScript objects cannot be compared.

Example

(x == y) true or false?

let x = new String("John");
let y = new String("John");

Output

false

----------------------

Example

(x  ===  y) true or false?

let x = new String("John");
let y = new String("John");

Output

false


Basic String Methods

  • Javascript strings are primitive and immutable: All string methods produce a new string without altering the original string.
  • All string methods return a new string. They don't modify the original string.

  • Strings are immutable: Strings cannot be changed, only replaced.

JavaScript String Length

The length property returns the length of a string:

Example

let text = "JavaScript";
let length = text.length;

Output

10

Extracting String Characters

There are 4 methods for extracting string characters:

  • The at(position) Method
  • The charAt(position) Method
  • The charCodeAt(position) Method
  • Using property access [] like in arrays

JavaScript String charAt():

  • The charAt() method returns the character at a specified index (position) in a string:

Example

let text = "HELLO WORLD";
let char = text.charAt(0);

Output

H

--------------------------------------------

JavaScript String charCodeAt()

  • The charCodeAt() method returns the code of the character at a specified index in a string:

Example

let text = "HELLO WORLD";
let char = text.charCodeAt(0);

Output

72

-----------------------------

JavaScript String at()

  • ES2022 introduced the string method at():

  • The at() method returns the character at a specified index (position) in a string.

Example

Get the third letter of name:

const name = "W3Schools";
let letter = name.at(2);

Output

S

Note

  • The at() method is a new addition to JavaScript.
  • It allows the use of negative indexes while charAt() do not.
  • Now you can use myString.at(-2) instead of charAt(myString.length-2).

Example

Get the third letter of name:

let myString = "Hello, World!";

console.log(myString.at(-2)); 

Output

d

Explanation:

  • The string "Hello, World!" has a length of 13.

  • .at(-2) retrieves the second-to-last character, which is 'd'.

------------------------------------

Property Access [ ]

Example

Get the third letter of name:

const name = "W3Schools";
let letter = 
 name[2];

Output

S

--------------------------------

Note

  • Property access might be a little unpredictable:
  • It makes strings look like arrays (but they are not)
  • If no character is found, [ ] returns undefined, while charAt() returns an empty string.
  • It is read only. str[0] = "A" gives no error (but does not work!)

Example

let text = "HELLO WORLD";
text[0] = "A";    // Gives no error, but does not work

Extracting String Parts

There are 3 methods for extracting a part of a string:

  • slice(start, end)
  • substring(startend)
  • substr(start, length): The substr() method is removed (deprecated) in the latest JavaScript standard.

JavaScript String slice()

  • slice() extracts a part of a string and returns the extracted part in a new string.
  • The method takes 2 parameters: start position, and end position (end not included).

Example

Slice out a portion of a string from position 7 to position 13:

let text = "Apple, Banana, Kiwi";
let part = text.slice(713);

Output

Banana

Note

  • JavaScript counts positions from zero.
  • First position is 0.
  • Second position is 1.

--------------------------------

Example

If you omit the second parameter, the method will slice out the rest of the string:

let text = "Apple, Banana, Kiwi";
let part = text.slice(7);

Output

Banana, Kiwi

--------------------------------

Example

If a parameter is negative, the position is counted from the end of the string:

let text = "Apple, Banana, Kiwi";
let part = text.slice(-12);

Output

Banana, Kiwi

-------------------------------

Example

This example slices out a portion of a string from position -12 to position -6:

let text = "Apple, Banana, Kiwi";
let part = text.slice(-12, -6);

Output

Banana


JavaScript String substring()

  • substring() is similar to slice().
  • If you omit the second parameter, substring() will slice out the rest of the string.
  • The difference is that start and end values less than 0 are treated as 0 in substring().

Example

let str = "Apple, Banana, Kiwi";
let part = str.substring(713);

Output

Banana


Converting to Upper and Lower Case

  • A string is converted to upper case with toUpperCase():
  • A string is converted to lower case with toLowerCase():

JavaScript String toUpperCase()

Example

let text1 = "Hello World!";
let text2 = text1.toUpperCase();

Output

HELLO WORLD!

---------------------------------------------------

JavaScript String toLowerCase()

Example

let text1 = "Hello World!";       // String
let text2 = text1.toLowerCase();

Output

hello world!


JavaScript String concat()

  • concat() joins two or more strings:

Example

let text1 = "Hello";
let text2 = "World";
let text3 = text1.concat(" ", text2);

Output

Hello World!

-----------------------------------------

  • The concat() method can be used instead of the plus operator. These two lines do the same:

Example

text = "Hello" + " " + "World!";
text = "Hello".concat(" ""World!");


JavaScript String trim()

  • In JavaScript, there are three main trim methods used to remove whitespace from strings:

1. trim()

  • Removes whitespace from both the beginning and end of the string.

Example

let str = " Hello, World! ";

console.log(str.trim()); 

Output

"Hello, World!"

-------------------------------

2. trimStart() (or trimLeft())

  • Removes whitespace only from the beginning of the string.

Example

let str = "   Hello, World!   ";

console.log(str.trimStart()); 

Output

"Hello, World!   "

-------------------------------

3. trimEnd() (or trimRight())

  • Removes whitespace only from the end of the string.

Example

let str = "   Hello, World!   ";

console.log(str.trimEnd()); 

Output

 "   Hello, World!"


JavaScript String Padding

In JavaScript, you can use string padding methods to add characters to the beginning or end of a string. The two main methods are:

1️⃣ padStart(targetLength, padString)

  • Pads the beginning of the string until it reaches the specified targetLength.

  • Uses padString (optional) to fill the extra space. If omitted, spaces (" ") are used by default.

Example

  • let str = "42";

    console.log(str.padStart(5, "0")); 

Output

  • "00042"

-------------------------------

  • To pad a number, convert the number to a string first.

Example

let numb = 5;
let text = numb.toString();
let padded = text.padStart(4,"0");

Output

"0005"

-----------------------------------------------------

2️⃣ padEnd(targetLength, padString)

  • Pads the end of the string until it reaches the specified targetLength.

  • Uses padString (optional) to fill the extra space. If omitted, spaces (" ") are used by default.

Example

let str = "42";

console.log(str.padEnd(5, "0"));

Output

"42000"


JavaScript String repeat()

  • The repeat() method in JavaScript is used to repeat a string a specified number of times and return a new string.
  • count → The number of times to repeat the string (must be a non-negative integer).

Syntax

string.repeat(count)

Example 1

let str = "Hello ";

console.log(str.repeat(3)); 

Output

"Hello Hello Hello "

-----------------------------------------

Example 2

  • If count is 0, it returns an empty string:

console.log("Hello".repeat(0));

Output

""

-----------------------------------------

Example 3

  • If count is negative, it throws an error:

console.log("Hello".repeat(-1));

Output

Uncaught RangeError

-----------------------------------------

Example 4

  • If count is a decimal, it gets floored (converted to an integer):

console.log("Hi".repeat(2.5));

Output

"HiHi"


JavaScript String replace()

  • The replace() method in JavaScript is used to replace a specified value in a string with another value.
  • It does not modify the original string but returns a new one with the replacements.

  • The replace() method is case sensitive.

Syntax

string.replace(searchValue, newValue)


Example 1

  • Replacing the first occurrence of a word

let text = "Hello World! Welcome to the World!";

let newText = text.replace("World", "Universe");

console.log(newText);

Output

"Hello Universe! Welcome to the World!"

Only the first occurrence of "World" is replaced.

-----------------------------------------------

Note

Regular expressions are written without quotes.

Example 2

  • Using Regular Expressions for global replacement

let text = "Hello World! Welcome to the World!";

let newText = text.replace(/World/g, "Universe");

console.log(newText);

Output

"Hello Universe! Welcome to the Universe!"

The /g flag makes it replace all occurrences.

-----------------------------------------------

Example 3

  • Case-Insensitive Replacement

let text = "Hello world!";

let newText = text.replace(/WORLD/i, "Universe");

console.log(newText);

Output

"Hello Universe!"

The /i flag makes it case-insensitive.


JavaScript String replaceAll()

  • In JavaScript, the replaceAll() method is used to replace all occurrences of a specified substring or regular expression in a string with another string.

Syntax

string.replaceAll(searchValue, newValue)


Example 1

  • Replacing all occurrences of a substring

let text = "Hello world, welcome to the world!";

let newText = text.replaceAll("world", "JavaScript");

console.log(newText);

Output

"Hello JavaScript, welcome to the JavaScript!"

-----------------------------------------------

Note

  • If searchValue is a regular expression, it must have the global (g) flag; otherwise, it throws an error.

Example 2

  • Using Regular Expressions

let text = "Hello 123, this is 123!";

let newText = text.replaceAll(/\d+/g, "XYZ");

console.log(newText);

Output

"Hello XYZ, this is XYZ!"


JavaScript String split()

  • In JavaScript, the split() method is used to split a string into an array of substrings based on a specified delimiter.
  • A string can be converted to an array with the split() method.

Example

text.split(",")    // Split on commas
text.split(" ")    // Split on spaces
text.split("|")    // Split on pipe

--------------------------------------------

Example 1

  • Splitting a string by a space

let text = "Hello JavaScript World";

let words = text.split(" ");

console.log(words);

Output

[ 'Hello', 'JavaScript', 'World' ]

-----------------------------------------------

Example 2

  • Splitting a string by a comma

let text = "apple,banana,orange";

let fruits = text.split(",");

console.log(fruits);

Output

[ 'apple', 'banana', 'orange' ]

--------------------------------------------

Example 3

  • Limiting the number of splits

let text = "one-two-three-four";

let parts = text.split("-", 2);

console.log(parts);

Output

[ 'one', 'two' ]

-----------------------------------------------

Example 4

  • Splitting a string into individual characters

let text = "Hello";

let chars = text.split("");

console.log(chars);

Output

[ 'H', 'e', 'l', 'l', 'o' ]

-----------------------------------------------

Example 5

  • Using a Regular Expression

let text = "apple123banana456cherry";

let result = text.split(/\d+/);

console.log(result);

Output

 [ 'apple', 'banana', 'cherry' ]

---------------------------------

Edge Cases

  • If the separator is an empty string (""), the string splits into individual characters.
  • If the separator does not exist in the string, the entire string is returned as a single-element array.
  • If the separator is undefined, the method returns an array containing the entire string.

Example 

console.log("Hello".split("")); // [ 'H', 'e', 'l', 'l', 'o' ]

console.log("Hello".split("x")); // [ 'Hello' ]

console.log("Hello".split()); // [ 'Hello' ]

========================================================================

JavaScript Operators

There are different types of JavaScript operators:

  • Arithmetic Operators
  • Assignment Operators
  • Comparison Operators
  • String Operators
  • Logical Operators
  • Bitwise Operators
  • Ternary Operators
  • Type Operators


JavaScript Arithmetic Operators

Arithmetic Operators are used to perform arithmetic on numbers:

 Example

let a = 3;
let x = (100 + 50) * a;


  • A typical arithmetic operation operates on two numbers.
  • The two numbers can be literals, variables or expressions.
  • In arithmetic, the division of two integers produces a quotient and a remainder.

  • In mathematics, the result of a modulo operation is the remainder of an arithmetic division.

Operators and Operands

  • The numbers (in an arithmetic operation) are called operands.
  • The operation (to be performed between the two operands) is defined by an operator.


---------------------------------------------------------

JavaScript Assignment Operators

  • Assignment operators assign values to JavaScript variables.
  • The Addition Assignment Operator (+=) adds a value to a variable.

Assignment

let x = 10;
x += 5;


---------------------------------------------------------

JavaScript Comparison Operators


---------------------------------------------------------

JavaScript String Comparison

All the comparison operators above can also be used on strings:

Example

let text1 = "A";
let text2 = "B";
let result = text1 < text2;

Note

  • When used on strings, the + operator is called the concatenation operator.
  • If you add a number and a string, the result will be a string!

---------------------------------------------------------

JavaScript Logical Operators


---------------------------------------------------------

JavaScript Bitwise Operators

---------------------------------------------------------

JS ternary operator

  • In JavaScript, the ternary operator (condition ? expr1 : expr2) is a concise way to write an if-else statement.

Syntax

condition ? expressionIfTrue : expressionIfFalse;

  • If condition is true, it returns expressionIfTrue.
  • If condition is false, it returns expressionIfFalse.
  • ---------------------------------------------------------

    🔍 The Nullish Coalescing Operator (??)

    📌 What is it?

    The ?? operator returns the right-hand value only if the left-hand value is null or undefined.

    Syntax

    let result = value ?? "default";


    • If value is null or undefined, then result becomes "default".
    • Otherwise, result is just value.

    Example

    let username = null;

    let displayName = username ?? "Guest";

    console.log(displayName); // "Guest"

    🧠 When to Use It?

    Use ?? when you're dealing with:

    • Default configuration values

    • Optional parameters

    • User input that might be undefined

    Example

    function greet(name) {

    let finalName = name ?? "Stranger";

    console.log(`Hello, ${finalName}!`);

    }

    greet(); // Hello, Stranger!

    greet("Venu"); // Hello, Venu!

    The Optional Chaining Operator (?.)

    The Optional Chaining Operator (?.) is a lifesaver when you're working with deeply nested objects or data from APIs where things might be null or undefined.

    🔍 What is Optional Chaining (?.)?

    It lets you safely access nested properties without throwing an error if a part of the chain is null or undefined.

    📌 Basic Syntax:

    object?.property

    object?.[expression]

    object?.method?.()

     Example 1: Basic Property Access

    let user = {

    name: "Venu",

    address: {

    city: "Hyderabad"

    }

    };

    console.log(user.address?.city); // "Hyderabad"

    console.log(user.address?.zipcode); // undefined (✅ no error)

    console.log(user.contact?.email); // undefined (✅ no error)

     Example 2: Method Access

    let user = {

    sayHi() {

    return "Hello!";

    }

    };

    console.log(user.sayHi?.()); // "Hello!"

    console.log(user.sayBye?.()); // undefined (no error)

     Example 3: Optional Chaining with Arrays

    let users = [{ name: "Alice" }, null, { name: "Bob" }];

    users.forEach(user => {

    console.log(user?.name); // prints "Alice", undefined, "Bob"

    });

    optional chaining is only for reading/accessing, not writing.

    ?. checks safely if the property exists (without throwing an error).
    ?? gives a fallback only if the result is null or undefined.
    -------------------------------------------------------

    JavaScript Type Operators

    • In JavaScript, type operators are used to determine or manipulate the type of a value. The two main type-related operators are:

    1.typeof operator    
    • The typeof operator returns a string representing the type of a value.

    Syntax

    typeof operand;

    Example

    console.log(typeof 42); // "number"

    console.log(typeof "Hello"); // "string"

    console.log(typeof true); // "boolean"

    console.log(typeof undefined); // "undefined"

    console.log(typeof null); // "object" (historical bug in JS)

    console.log(typeof {}); // "object"

    console.log(typeof []); // "object" (arrays are objects)

    console.log(typeof function(){}); // "function"

    console.log(typeof NaN); // "number"

    2.instanceof Operator

    • The instanceof operator checks whether an object is an instance of a particular class or constructor function.

    Syntax

    object instanceof Constructor;

    Example

    class Car {}

    let myCar = new Car();

    console.log(myCar instanceof Car); // true

    console.log(myCar instanceof Object); // true (because all objects inherit from Object)

    console.log([] instanceof Array); // true

    console.log([] instanceof Object); // true

    console.log(function(){} instanceof Function); // true

    JavaScript Type Conversion

    JavaScript variables can be converted to a new variable and another data type:

    • By the use of a JavaScript function
    • Automatically by JavaScript itself


    Converting Strings to Numbers

    The global method Number() converts a variable (or a value) into a number.

    Examples

    Number("3.14")  //converts to a number (like 3.14).

    Number(Math.PI) //converts to a number 3.141592653589793

    Number(" ")  //converts to 0

    Number("")   //converts to 0

    Number("99 88")  //converts to NaN (Not a Number)

    Number("John")   //converts to NaN (Not a Number)

    -------------------------------------------------------------------------------------------

    Converting Numbers to String

    • The global method String() can convert numbers to strings.
    • It can be used on any type of numbers, literals, variables, or expressions:

    Examples

    String(x)         // returns a string from a number variable x
    String(123)       // returns a string from a number literal 123
    String(100 + 23)  // returns a string from a number from an expression

    --------------------------------------------------

    Converting Dates to Numbers

    • The global method Number() can be used to convert dates to numbers.

    d = new Date();
    Number(d)       
       // returns 1404568027739

    • The date method getTime() does the same.

    d = new Date();
    d.getTime()    
        // returns 1404568027739

    --------------------------------------

    Converting Dates to Strings

    • The global method String() can convert dates to strings.

    String(Date())  // returns "Thu Jul 17 2014 15:38:19 GMT+0200 (W. Europe Daylight Time)"
    Date().toString()  // returns "Thu Jul 17 2014 15:38:19 GMT+0200 (W. Europe Daylight Time)"

    ---------------------------------------------------

    Converting Booleans to Numbers

    • The global method Number() can also convert booleans to numbers.

    Number(false)     // returns 0
    Number(true)      // returns 1

    ---------------------------------------------

    Converting Booleans to Strings

    • The global method String() can convert booleans to strings.

    String(false)      // returns "false"
    String(true)       // returns "true"

    • The Boolean method toString() does the same.

    false.toString()   // returns "false"
    true.toString()    // returns "true"

    ----------------------------------------

    Automatic Type Conversion

    • When JavaScript tries to operate on a "wrong" data type, it will try to convert the value to a "right" type.
    • The result is not always what you expect:

    Examples

    5 + null    // returns 5         because null is converted to 0
    "5" + null  // returns "5null"   because null is converted to "null"
    "5" + 2     // returns "52"      because 2 is converted to "2"
    "5" - 2     // returns 3         because "5" is converted to 5
    "5" * "2"   // returns 10        because "5" and "2" are converted to 5 and 2
     

    ============================

    JavaScript Variables

    var vs let vs const: Key Differences:

    In JavaScript, we use three keywords to declare variables: varlet, and const. While they all serve the purpose of creating variables, they each behave differently and are used in different contexts

    var (Variable)

    Characteristics of var:

    • Function-scoped: Variables declared with var are scoped to the nearest function block, not the nearest code block.
    • Hoistingvar declarations are hoisted to the top of their scope, but their values are not. This means that the variable is created in memory before the code runs, but it will be undefined until the assignment happens.
    • Re-declaration: You can declare a variable multiple times in the same scope using var, which can sometimes lead to unexpected behavior or bugs.

    Example:

    javascript

    function example() { console.log(x); // Output: undefined, because of hoisting var x = 10; console.log(x); // Output: 10 } example();

    In the above example:

    • The var x declaration is hoisted to the top, but the assignment happens only after the first console.log(), so the value of x is undefined at that point.
    Example 1: var is Function Scoped
    function testVar() {
        if (true) {
            var x = 10;
        }
        console.log(x); // ✅ Works (not block-scoped)
    }
    testVar();
    ✅ var ignores {} and is accessible outside the if block.

    2. let (Block-scoped Variable)

    Characteristics of let:

    • Block-scopedlet is scoped to the nearest block (enclosed in {}), such as loops or conditionals, rather than a function.
    • Hoisting: Like varlet is hoisted, but it is not initialized until the code execution reaches the declaration. If you try to use the variable before its declaration, you will get a ReferenceError.
    • Re-declaration: You cannot redeclare a variable within the same block scope. However, you can declare it in different blocks.

    Example:

    javascript

    function example() { //console.log(x); // Uncaught ReferenceError: Cannot access 'x' before initialization let x = 10; console.log(x); // Output: 10 } example();

    Here:

    • If you uncomment the first console.log(x);, it will throw an error because let is not hoisted like var and cannot be used before the declaration.
    Example 2: let is Block Scoped
    function testLet() {
        if (true) {
            let y = 20;
        }
        console.log(y); // ❌ Error (y is not defined)
    }
    testLet();
    ❌ let follows block scope and is not accessible outside {}.
    Example 3: let allows reassignment
    let name = "John";
    name = "Doe"; // ✅ Allowed
    console.log(name); // Output: Doe

    3. const (Constant Variable)

    Characteristics of const:

    • Block-scoped: Like letconst is also block-scoped.
    • Cannot be re-assigned: Once a const variable is assigned a value, it cannot be reassigned to another value.
    • Must be initialized: When declaring a const variable, you must assign it a value immediately. It cannot be left uninitialized.
    • Objects and Arrays: While you cannot reassign a const variable, if the const is an object or an array, you can still modify its contents (mutate the object/array), but you cannot reassign the whole object or array.

    Example:

    javascript

    function example() { const x = 10; console.log(x); // Output: 10 // x = 20; // Uncaught TypeError: Assignment to constant variable. } example();
    • Here, const x = 10 cannot be reassigned to 20 because constants cannot be reassigned.
    Example 4: const cannot be reassigned
    const PI = 3.14;
    PI = 3.1416; // ❌ Error: Assignment to constant variable

    Example 5: const is Block Scoped
    if (true) {
        const num = 100;
    }
    console.log(num); // ❌ Error: num is not defined

    When to Use varlet, and const?

    • Use var: Avoid using var in modern JavaScript unless working with legacy code. It’s more error-prone due to hoisting and re-declaration issues.
    • Use let: When you need a variable whose value will change over time (i.e., loops, conditionals), and you want to ensure it is scoped to a block.
    • Use const: When you want to create a variable that should not be reassigned. This is generally the preferred choice for constants or when dealing with objects and arrays where the reference does not need to change.

    Hoisting Behavior

    All three are hoisted, but they behave differently:

    console.log(a); // ✅ undefined (hoisted)
    var a = 10;

    console.log(b); // ❌ Error: Cannot access 'b' before initialization
    let b = 20;

    console.log(c); // ❌ Error: Cannot access 'c' before initialization
    const c = 30;


    -----------------------------------------------------------------------------------------------

    Quiz: Choose the Correct Answer

    1️⃣ Which keyword is function-scoped in JavaScript?

    • A) let
    • B) const
    • C) var
    • D) All of the above

    ✅ Answer: C) var

    2️⃣ What happens when you try to reassign a const variable?

    • A) It changes the value
    • B) It throws an error
    • C) It works only inside a function
    • D) It creates a new variable

    ✅ Answer: B) It throws an error

    3️⃣ Which variable keyword allows redeclaration?

    • A) var
    • B) let
    • C) const
    • D) Both let and const

    ✅ Answer: A) var

    4️⃣ What will be the output of this code?

    Fix the errors in this code and explain why it didn’t work.

     Original Code with Errors:

    console.log(num);

    let num = 10; // ❌ Error 1


    const age; 

    age = 25; // ❌ Error 2


    var count = 5;

    var count = 10;

    let count = 15; // ❌ Error 3


    if (true) {

        const pi = 3.14;

    }

    console.log(pi); // ❌ Error 4


    ❌ Debugging the Original Code & Fixing Errors

    🚨 Original Code with Errors:

    --------------------------------------------------------------------------------

    ✅ Corrected Code

    let num = 10;

    console.log(num); // ✅ Now it works fine


    const age = 25; // ✅ Initialize const at declaration


    var count = 5;

    var count = 10; // ✅ `var` allows redeclaration


    let newCount = 15; // ✅ Renamed `count` to avoid redeclaring with let


    if (true) {

        const pi = 3.14;

        console.log(pi); // ✅ Now `pi` is accessed inside the same block

    }

    Explanation of Fixes

    🚨 Error 1: Using a let Variable Before Declaration

    console.log(num);
    let num = 10;

    ❌ Problem:

    • let variables are not hoisted in a way that allows access before declaration.
    • Accessing num before its declaration throws a ReferenceError.

    ✅ Fix:
    Move the let num = 10; above console.log(num);

    🚨 Error 2: Declaringconst Without Initializing

    const age;

    age = 25;

    ❌ Problem:

    • const must be initialized at the time of declaration.
    • The above code throws a SyntaxError.

    ✅ Fix:
    Declare and initialize const age = 25; in one step.

     Error 3: Redeclaring Variables with let

    var count = 5;

    var count = 10; // ✅ Works fine

    let count = 15; // ❌ Error: Cannot redeclare using let

    ❌ Problem:

    • var allows redeclaration, but let does not.
    • Redeclaring count using let throws a SyntaxError.

    ✅ Fix:
    Rename the let count = 15; to a different variable, e.g., let newCount = 15;

    🚨 Error 4: Accessingconst Variable Outside Its Block Scope

    if (true) {

        const pi = 3.14;

    }

    console.log(pi); // ❌ Error: pi is not defined

    ❌ Problem:

    • const pi = 3.14; is block-scoped, meaning it only exists inside the if block.
    • Trying to access pi outside the block throws a ReferenceError.

    ✅ Fix:
    Move console.log(pi); inside the if block.

    🔥 Final Takeaways

    1️⃣ var is function-scopedlet and const are block-scoped.
    2️⃣ var allows redeclaration, but let and const do not.
    3️⃣ const must be initialized when declared.
    4️⃣ let and const are not hoisted like var.

    ============================================================

    JavaScript Arrays

    • An array is a single variable that holds multiple values.
    • It’s zero-indexed.

    Creating an Array

    Syntax

    const array_name = [item1item2, ...];      

    Array Declaration

    let arr = []; // Empty array

    let numbers = [1, 2, 3, 4]; // Array with numbers

    JavaScript Keyword new

    The following example also creates an Array, and assigns values to it:

    Example

    const cars = new Array("Saab""Volvo""BMW");

    Accessing Array Elements

    You access an array element by referring to the index number:

    Example

    const cars = ["Saab""Volvo""BMW"];
    let car = cars[0];

    output

    Saab

    Note: Array indexes start with 0.

    [0] is the first element. [1] is the second element.

    Changing an Array Element

    This statement changes the value of the first element in cars:

    Example

    const cars = ["Saab""Volvo""BMW"];
    cars[0] = "Opel";

    output

    Opel,Volvo,BMW

    Converting an Array to a String

    The JavaScript method toString() converts an array to a string of (comma separated) array values.

    Example

    const fruits = ["Banana""Orange""Apple""Mango"];
     fruits.toString();

    Result:

    Banana,Orange,Apple,Mango

    Arrays are Objects

    • Arrays are a special type of objects. The typeof operator in JavaScript returns "object" for arrays.
    • But, JavaScript arrays are best described as arrays.
    • Arrays use numbers to access its "elements". In this example, person[0] returns John:

    Array:

    const person = ["John""Doe"46];

    Objects use names to access its "members". In this example, person.firstName returns John:

    Object:

    const person = {firstName:"John", lastName:"Doe", age:46};

    Accessing the First Array Element

    Example

    const fruits = ["Banana""Orange""Apple""Mango"];
    let fruit = fruits[0];

    output

    Banana

    Accessing the Last Array Element

    Example

    const fruits = ["Banana""Orange""Apple""Mango"];
    let fruit = fruits[fruits.length - 1];

    output

    Mango

    Adding Array Elements

    The easiest way to add a new element to an array is using the push() method:

    Example

    const fruits = ["Banana""Orange""Apple"];
    fruits.push("Lemon");  // Adds a new element (Lemon) to fruits

    output

    Banana,Orange,Apple,Lemon

    Associative Arrays

    • Many programming languages support arrays with named indexes.
    • Arrays with named indexes are called associative arrays (or hashes).
    • JavaScript does not support arrays with named indexes.
    • In JavaScript, arrays always use numbered indexes.  

    Example

    const person = [];
    person[0] = "John";
    person[1] = "Doe";
    person[2] = 46;
    person.length;    // Will return 3
    person[0];        // Will return "John"

    Example:

    const person = [];
    person["firstName"] = "John";
    person["lastName"] = "Doe";
    person["age"] = 46;
    person.length;     // Will return 0
    person[0];         // Will return undefined

    The Difference Between Arrays and Objects

    • In JavaScript, arrays use numbered indexes.  
    • In JavaScript, objects use named indexes.
    • Arrays are a special kind of objects, with numbered indexes.

    When to Use Arrays. When to use Objects.

    • JavaScript does not support associative arrays.
    • You should use objects when you want the element names to be strings (text).
    • You should use arrays when you want the element names to be numbers.

    How to Recognize an Array

    • A common question is: How do I know if a variable is an array?
    • The problem is that the JavaScript operator typeof returns "object":

    Example

    const fruits = ["Banana""Orange""Apple"];
    let type = typeof fruits;

    output

    object

    • The instanceof operator returns true if an object is created by a given constructor:

    const fruits = ["Banana""Orange""Apple"];

    (fruits instanceof Array);

    output

    object

    JavaScript Array Methods


    JavaScript Array length

    • The length property returns the length (size) of an array:

    Example

    const fruits = ["Banana""Orange""Apple""Mango"];
    let size = fruits.length;

    output

    4

    JavaScript Array toString()

    • The JavaScript method toString() converts an array to a string of (comma separated) array values.

    Example

    const fruits = ["Banana""Orange""Apple""Mango"];
    document.getElementById("demo").innerHTML = fruits.toString();

    Result:

    Banana,Orange,Apple,Mango

    JavaScript Array at()

     The array method at():

    Examples

    Get the third element of fruits using at():

    const fruits = ["Banana""Orange""Apple""Mango"];
    let fruit = fruits.at(2);

    Get the third element of fruits using []:

    const fruits = ["Banana""Orange""Apple""Mango"];
    let fruit = fruits[2];

    output

    Apple

    • The at() method returns an indexed element from an array.
    • The at() method returns the same as [].

    JavaScript Array join()

    • The join() method also joins all array elements into a string.
    • It behaves just like toString(), but in addition you can specify the separator:

    Example

    const fruits = ["Banana""Orange""Apple""Mango"];
     fruits.join(" * ");

    Result:

    Banana * Orange * Apple * Mango

    Popping and Pushing

    • When you work with arrays, it is easy to remove elements and add new elements.
    • This is what popping and pushing is:
    • Popping items out of an array, or pushing items into an array.

    1. JavaScript Array pop()

    The pop() method removes the last element from an array:

    Example

    const fruits = ["Banana""Orange""Apple""Mango"];
    fruits.pop();

    output

    Banana,Orange,Apple

    2. JavaScript Array push()

    The push() method adds a new element to an array (at the end):

    Example

    const fruits = ["Banana""Orange""Apple""Mango"];
    fruits.push("Kiwi"
    );

    output

    Banana,Orange,Apple,Mango,Kiwi

    JavaScript Array shift()

    The shift() method removes the first array element and "shifts" all other elements to a lower index.

    Returns that removed element.

    Example

    const fruits = ["Banana""Orange""Apple""Mango"];
    fruits.shift();

    output

    Banana

    JavaScript Array unshift()

    The unshift() method adds a new element to an array (at the beginning), and "unshifts" older elements:

    Example

    const fruits = ["Banana""Orange""Apple""Mango"];
    fruits.unshift("Lemon");

    output

    Lemon,Banana,Orange,Apple,Mango

    JavaScript Array concat()

    The concat() method creates a new array by merging (concatenating) existing arrays:

    Example (Merging Two Arrays)

    const myGirls = ["Cecilie""Lone"];
    const myBoys = ["Emil""Tobias""Linus"];

    const myChildren = myGirls.concat(myBoys);

    output

    Cecilie,Lone,Emil,Tobias,Linus

    Note

    • The concat() method does not change the existing arrays. It always returns a new array.
    • The concat() method can take any number of array arguments.

    Example (Merging Three Arrays)

    const arr1 = ["Cecilie""Lone"];
    const arr2 = ["Emil""Tobias""Linus"];
    const arr3 = ["Robin""Morgan"];
    const myChildren = arr1.concat(arr2, arr3);

    output

    Cecilie,Lone,Emil,Tobias,Linus,Robin,Morgan

    • The concat() method can also take strings as arguments:

    Example (Merging an Array with Values)

    const arr1 = ["Emil""Tobias""Linus"];
    const myChildren = arr1.concat("Peter");
     

    output

    Emil,Tobias,Linus,Peter

    Array copyWithin()

    The copyWithin() method copies array elements to another position in an array:

    Examples

    Copy to index 2, all elements from index 0:

    const fruits = ["Banana""Orange""Apple""Mango"];
    fruits.copyWithin(20);

    output

    Banana,Orange,Banana,Orange

    Note

    • The copyWithin() method overwrites the existing values.
    • The copyWithin() method does not add items to the array.
    • The copyWithin() method does not change the length of the array.

    JavaScript Array flat()

    • Flattening an array is the process of reducing the dimensionality of an array.
    • Flattening is useful when you want to convert a multi-dimensional array into a one-dimensional array.
    • The flat() method creates a new array with sub-array elements concatenated to a specified depth.

    Example

    const myArr = [[1,2],[3,4],[5,6]];
    const newArr = myArr.flat();

    output

    1,2,3,4,5,6

    Splicing and Slicing Arrays

    The splice() method adds new items to an array.

    The slice() method slices out a piece of an array.


    1. JavaScript Array splice()

    • The splice() method can be used to add new items to an array:

    Example

    const fruits = ["Banana""Orange""Apple""Mango"];
    fruits.splice(20"Lemon""Kiwi");

    output

    Banana,Orange,Lemon,Kiwi,Apple,Mango

    • The first parameter (2) defines the position where new elements should be added (spliced in).
    • The second parameter (0) defines how many elements should be removed.
    • The rest of the parameters ("Lemon" , "Kiwi") define the new elements to be added.

    --------------------

    • The splice() method returns an array with the deleted items:

    Example

    const fruits = ["Banana""Orange""Apple""Mango"];
    fruits.splice(22"Lemon""Kiwi");

    output

    Banana,Orange,Lemon,Kiwi

    ---------------------

    Using splice() to Remove Elements

    You can use splice() to remove elements without leaving "holes" in the array:

    Example

    const fruits = ["Banana""Orange""Apple""Mango"];
    fruits.splice(01);

    output

    Orange,Apple,Mango

    • The first parameter (0) defines the position where new elements should be added (spliced in).
    • The second parameter (1) defines how many elements should be removed.
    • The rest of the parameters are omitted. No new elements will be added.

    ------------------

    "holes in arrays" scenario using splice() vs delete:

    When we talk about "holes" in an array in JavaScript, we’re usually referring to undefined or empty slots that can exist when items are removed or skipped improperly—especially with methods like delete.

    🚫 Example of Creating "Holes" (Bad Practice):

    const fruits = ["Banana", "Orange", "Apple", "Mango"];

    delete fruits[0];

    console.log(fruits); // [ <1 empty item>, "Orange", "Apple", "Mango" ]

    console.log(fruits.length); // 4


  • delete removes the value but doesn’t re-index or reduce the length.
  • So, index 0 becomes an empty slot (a "hole").

  • ✅ Using splice() (No Holes – Good Practice):

    const fruits = ["Banana", "Orange", "Apple", "Mango"];

    fruits.splice(0, 1); // Removes 1 item at index 0

    console.log(fruits); // ["Orange", "Apple", "Mango"]

    console.log(fruits.length); // 3

  • splice() removes the element and shifts the rest left, so the array stays clean and compact.
  • No undefined, no holes—just a proper resized array.
  • 2. JavaScript Array slice()

    The slice() method slices out a piece of an array into a new array:

    Example

    Slice out a part of an array starting from array element 1 ("Orange"):

    const fruits = ["Banana""Orange""Lemon""Apple""Mango"];
    const citrus = fruits.slice(1);

    output

    Orange,Lemon,Apple,Mango

    Note

    • The slice() method creates a new array.
    • The slice() method does not remove any elements from the source array.


    The slice() method can take two arguments like slice(1, 3).

    The method then selects elements from the start argument, and up to (but not including) the end argument.

    Example

    const fruits = ["Banana""Orange""Lemon""Apple""Mango"];
    const citrus = fruits.slice(13);

    output

    Orange,Lemon

    JavaScript Array toSpliced()

    The difference between the new toSpliced() method and the old splice() method is that the new method creates a new array, keeping the original array unchanged, while the old method altered the original array.

    Example

    const months = ["Jan""Feb""Mar""Apr"];
    const spliced = months.toSpliced(01);

    output

    Feb,Mar,Apr

    JavaScript Array Search

    JavaScript Array indexOf()

    • The indexOf() method searches an array for an element value and returns its position.

    Syntax

    array.indexOf(item, start)
    itemRequired. The item to search for.
    startOptional. Where to start the search. Negative values will start at the given position counting from the end, and search to the end.

    • Array.indexOf() returns -1 if the item is not found.
    • If the item is present more than once, it returns the position of the first occurrence.

    Note: The first item has position 0, the second item has position 1, and so on.

    Example

    [1, 2, 3, 2].indexOf(2); // returns 1

    ----------------------------

    JavaScript Array lastIndexOf()

    • Array.lastIndexOf() is the same as Array.indexOf(), but returns the position of the last occurrence of the specified element.

    Syntax

    array.lastIndexOf(item, start)
    itemRequired. The item to search for
    startOptional. Where to start the search. Negative values will start at the given position counting from the end, and search to the beginning

    Example

    [1, 2, 3, 2].lastIndexOf(2); // returns 3

    ------------------------

    JavaScript Array includes()

    •  This allows us to check if an element is present in an array (including NaN, unlike indexOf).

    Syntax

    array.includes(search-item)

    Array.includes() allows to check for NaN values. Unlike Array.indexOf().

    Example

    [1, 2, 3].includes(2); // returns true

    -----------------------------

    JavaScript Array find()

    The find() method returns the value of the first array element that passes a test function.

    Usagearr.find(callback)

    Returns: First element that matches the condition.

    Example

    [5, 12, 8, 130].find(el => el > 10); // returns 12

    ------------------------------

    JavaScript Array findIndex()

    The findIndex() method returns the index of the first array element that passes a test function.

    Usagearr.findIndex(callback)

    Returns: Index of first element that matches condition, or -1.

    Example

    [5, 12, 8, 130].findIndex(el => el > 10); // returns 1

    ------------------------------

    JavaScript Array findLast() Method

    The findLast() method that will start from the end of an array and return the value of the first element that satisfies a condition.

    Usagearr.findLast(callback)

    ReturnsLast element that matches the condition.

    Example

    [5, 12, 8, 130].findLast(el => el > 10); // returns 130

    ------------------------------

    JavaScript Array findLastIndex() Method

    The findLastIndex() method finds the index of the last element that satisfies a condition.

    Usagearr.findLastIndex(callback)

    Returns: Index of last element that matches condition, or -1.

    Example

    [5, 12, 8, 130].findLastIndex(el => el > 10); // returns 3

    • Use indexOf / includes for simple value lookups.
    • Use find / findIndex when you need logic-based searches (e.g., greater than).
    • Use findLast / findLastIndex to search from the end of the array.

    JavaScript Sorting Arrays

    JavaScript Array Sort Methods, categorized into Alphabetic Sort and Numeric Sort.


    Sorting an Array

    The sort() method sorts an array alphabetically:

    Example

    const fruits = ["Banana""Orange""Apple""Mango"];
    fruits.sort();

    output

    Apple,Banana,Mango,Orange

    ------------------------------

    Reversing an Array

    The reverse() method reverses the elements in an array:

    Example

    const fruits = ["Banana""Orange""Apple""Mango"];
    fruits.reverse();

    output

    Mango,Apple,Orange,Banana

    ------------------------------

    By combining sort() and reverse(), you can sort an array in descending order:

    Example

    const fruits = ["Banana""Orange""Apple""Mango"];
    fruits.sort();
    fruits.reverse();

    output

    Orange,Mango,Banana,Apple

    --------------------------

    JavaScript Array toSorted() Method

    The toSorted() method as a safe way to sort an array without altering the original array.

    The difference between toSorted() and sort() is that the first method creates a new array, keeping the original array unchanged, while the last method alters the original array.

    Example

    const months = ["Jan""Feb""Mar""Apr"];
    const sorted = months.toSorted();

    output

    Apr,Feb,Jan,Mar

    --------------------------

    JavaScript Array toReversed() Method

    The toReversed() method as a safe way to reverse an array without altering the original array.

    The difference between toReversed() and reverse() is that the first method creates a new array, keeping the original array unchanged, while the last method alters the original array.

    Example

    const months = ["Jan""Feb""Mar""Apr"];
    const reversed = months.toReversed();

    output

    Apr,Mar,Feb,Jan

    --------------------------

    Numeric Sort

    Example

    let nums = [10, 2, 30];

    nums.sort((a, b) => a - b); // Result: [2, 10, 30]

    👉 This sorts numbers from smallest to largest.

    • a - b means "sort in ascending order".

    • If you used b - a, it would sort in descending order.

    -------------------------------

    Random Sort (Shuffling)

    Example

    let items = [1, 2, 3, 4];

    items.sort(() => Math.random() - 0.5);  //[ 4, 3, 1, 2 ]

    👉 This mixes up the array randomly.
    ⚠️ Not perfect randomness, but fun for quick shuffles!

    -------------------------------

    Math.min()

    Example

    let nums = [3, 7, 1];

    Math.min(...nums);  // Result: 1

    👉 Gives the smallest number in the array

    -------------------------------

    Math.max()

    Example

    let nums = [3, 7, 1];

    Math.max(...nums);  // Result: 7

    👉 Gives the largest number in the array.

    -------------------------------

    Home Made Min

    Example

    let nums = [5, 2, 8];

    let min = nums.reduce((a, b) => (a < b ? a : b));  // Result: 2

    👉 This does the same as Math.min() but using logic (reduce method).

    -------------------------------

    Home Made Max

    Example

    let nums = [5, 2, 8];

    let max = nums.reduce((a, b) => (a > b ? a : b));  // Result: 8


    JavaScript Array Iteration


    🔁 Looping and Transforming Methods

    JavaScript Array forEach()

    • Runs a function on each item (does not return anything).

    Example

    let arr = [1, 2, 3];

    arr.forEach(num => console.log(num));

    output

    1 2 3

    👉 What is num?

    num is a parameter in the arrow function (num => console.log(num)).

    When forEach() runs, it iterates through each element of the array, and for every element, it calls the function with that element as the argument.

    So in this case:

    On 1st loop: num = 1

    • On 2nd loop: num = 2

    • On 3rd loop: num = 3

    It prints each of them one by one.

    -----------------------------------

    You can also write it like:

    Example

    let arr = [1, 2, 3];

    arr.forEach(function(num) {

      console.log(num);

    });

    output

    1 2 3

    -----------------------------------

    Or with index and array:

    Example

    let arr = [1, 2, 3];

    arr.forEach((num, index, array) => {

      console.log(`Index ${index}: ${num}`);

    });

    output

    Index 0: 1

    Index 1: 2

    Index 2: 3

    -----------------------------------

    JavaScript Array map()--Return new array

    • Creates a new array with modified values.

    Example

    let arr = [1, 2, 3];

    let doubled = arr.map(num => num * 2);

    console.log(doubled);

    output

    [ 2, 4, 6 ]

    -----------------------------------

    JavaScript Array flatMap()--Map + flatten

    • Like map(), but flattens the result into one level.
    • The flatMap() method first maps all elements of an array and then creates a new array by flattening the array.

    Example

    let arr = [1, 2];

    let result = arr.flatMap(num => [num, num * 2]);

    console.log(result);

    output

    [1, 2, 2, 4]

    -----------------------------------

    JavaScript Array filter()-– Filter items

    • Creates a new array with only matching items.

    Example

    let arr = [1, 5, 8]; let filtered = arr.filter(num => num > 3); console.log(filtered);

    output

    [5, 8]

    -----------------------------------

    JavaScript Array reduce()--– Reduce to one value

    • Turns the array into a single value (like sum or total).
    • The reduce() method works from left-to-right in the array.
    • The reduce() method does not reduce the original array.

    Example

    let arr = [1, 2, 3]; let sum = arr.reduce((a, b) => a + b, 0); console.log(sum);

    output

    6

    -----------------------------------

    JavaScript Array reduceRight()-- – Reduce from right

    • Same as reduce(), but works from right to left.
    • The reduceRight() works from right-to-left in the array. See also reduce().
    • The reduceRight() method does not reduce the original array.

    Example

    let arr = [1, 2, 3]; let result = arr.reduceRight((a, b) => a - b); console.log(result);

    output

    0 → (3 - 2 - 1)

    -----------------------------------

    ✅ Condition Checking Methods

    JavaScript Array every()--– All items match?

    • Returns true if all items match a condition.

    Example

    let arr = [10, 20, 30]; let allAbove5 = arr.every(num => num > 5); console.log(allAbove5);

    output

    true

    -----------------------------------

    JavaScript Array some()---– At least one match?

    • Returns true if at least one item matches.

    Example

    let arr = [3, 7, 1]; let hasAbove5 = arr.some(num => num > 5); console.log(hasAbove5);

    output

    true

    -----------------------------------

    🧱 Utility Methods

    JavaScript Array.from()-- – Convert to array

    • Converts something (like string or set) into an array.

    Example

    let str = "hello"; let arr = Array.from(str); console.log(arr);

    output

    ["h", "e", "l", "l", "o"]

    -----------------------------------

    JavaScript Array keys()---Get indexes

    • Returns an iterator of index numbers.

    Example

    let arr = ["a", "b", "c"]; for (let key of arr.keys()) { console.log(key); }

    output

    0, 1, 2

    -----------------------------------

    JavaScript Array entries()--Get index + value

    • Returns an iterator of [index, value] pairs.

    Example

    let arr = ["a", "b"]; for (let [index, value] of arr.entries()) { console.log(index, value); }

    output

    0 a 1 b

    -----------------------------------

    JavaScript Array with() Method--Replace one item (Immutable)

    • Makes a copy of the array with one value changed.

    Example

    let arr = [10, 20, 30]; let newArr = arr.with(1, 99); // Replace index 1 console.log(newArr);

    output

    [10, 99, 30]

    -----------------------------------

    JavaScript Array Spread (...)-- Copy or expand array

    • Expands an array or copies it.

    Example

    let arr = [1, 2, 3]; let copy = [...arr]; console.log(copy);

    output

    [1, 2, 3]

    ========================================================================

    JavaScript if, else, else if and Switch Statements


    Conditional statements are used to perform different actions based on different conditions.

    In JavaScript we have the following conditional statements:

    • Use if to specify a block of code to be executed, if a specified condition is true
    • Use else to specify a block of code to be executed, if the same condition is false
    • Use else if to specify a new condition to test, if the first condition is false
    • Use switch to specify many alternative blocks of code to be executed

    The if Statement

    Use the if statement to specify a block of JavaScript code to be executed if a condition is true.

    Syntax

    if (condition) {
      //  block of code to be executed if the condition is true
    }

     Note : that if is in lowercase letters. Uppercase letters (If or IF) will generate a JavaScript error.

    ✅ if Statement

    Used to execute code if a condition is true.

    let age = 18;

    if (age >= 18) {

    console.log("You are an adult.");

    }

    output

    You are an adult.

    ------------------------------------------------------------------------

    The else Statement

    Use the else statement to specify a block of code to be executed if the condition is false.

    if (condition) {
      //  block of code to be executed if the condition is true
    else {
      //  block of code to be executed if the condition is false
    }

     if...else Statement

    Executes one block if the condition is true, and another if it's false.

    let age = 16;

    if (age >= 18) {

    console.log("You are an adult.");

    } else {

    console.log("You are a minor.");

    }

    output

    You are a minor.
    ------------------------------------------------------------------------

    The else if Statement

    Use the else if statement to specify a new condition if the first condition is false.

    Syntax

    if (condition1) {
      //  block of code to be executed if condition1 is true
    else if (condition2) {
      //  block of code to be executed if the condition1 is false and condition2 is true
    else {
      //  block of code to be executed if the condition1 is false and condition2 is false
    }

     if...else if...else Statement

    Used to check multiple conditions.

    let score = 85;

    if (score >= 90) {

    console.log("Grade A");

    } else if (score >= 80) {

    console.log("Grade B");

    } else if (score >= 70) {

    console.log("Grade C");

    } else {

    console.log("Fail");

    }

    output

    Grade B

    ------------------------------------------------------------------------

    The Switch Statement

    Use the switch statement to select one of many code blocks to be executed.

    Syntax

    switch(expression) {
      case x:
        // code block
        break;
      case y:
        // code block
        break;
      default:
        // code block
    }

    This is how it works:

    • The switch expression is evaluated once.
    • The value of the expression is compared with the values of each case.
    • If there is a match, the associated block of code is executed.
    • If there is no match, the default code block is executed.

     switch Statement

    An alternative to if...else if...else for comparing the same variable to multiple values.

    let day = "Tuesday";

    switch (day) {

    case "Monday":

    console.log("Start of the week");

    break;

    case "Tuesday":

    console.log("Second day");

    break;

    case "Friday":

    console.log("Almost weekend!");

    break;

    default:

    console.log("It's just a regular day");

    }

    output
    Second day
    🔹 Use break to stop the execution once a case matches.
    🔹 default is optional and runs when no case matches.


    ✅ Truthy values in JavaScript

    (These evaluate to true in a condition)

    • Non-zero numbers (1-13.14, etc.)

    • Non-empty strings ("hello""0""false", etc.)

    • Objects ({}[])

    • Functions (function() {}, arrow functions)

    • The special values like new Date()new Error()

    • Infinity and -Infinity

    • Symbols (Symbol())

    • BigInt values (e.g., 1n-1n)


    ❌ Falsy values in JavaScript

    (These evaluate to false in a condition)

    • false

    • 0

    • -0

    • 0n (BigInt zero)

    • "" (empty string)

    • null

    • undefined

    • NaN (Not a Number)


    🔔 Remember:Anything not in the falsy list is truthy by default!

    ===================================

    Loops (For, While, For-in, For-of) Loops can execute a block of code a number of times. Different Kinds of Loops JavaScript supports different kinds of loops: • for - loops through a block of code a number of times • for/in - loops through the properties of an object • for/of - loops through the values of an iterable object • while - loops through a block of code while a specified condition is true • do/while - also loops through a block of code while a specified condition is true The For Loop 🔁 Basic Syntax: Syntax for (initialization; condition; increment) { // code to be executed }

    Example for (let i = 0; i < 5; i++) { console.log("Number:", i); }

    🔍 How it works: 1. Initialization: Executes once before the loop starts (let i = 0). 2. Condition: Checked before each iteration. If true, the loop runs (i < 5). 3. Increment: Executes after each loop iteration (i++).

    Output of the above example: Number: 0 Number: 1 Number: 2 Number: 3 Number: 4 The For In Loop The JavaScript for in statement loops through the properties of an Object: Syntax for (key in object) { // code block to be executed } Example const person = { name: "Venkateswari", age: 28, city: "Hyderabad" };

    for (let key in person) { console.log(key + ": " + person[key]); } output name: Venkateswari age: 28 city: Hyderabad

    ⚠️ Notes: • for...in loops over keys, not values. • It works on objects, not ideal for arrays (though it technically works). • For arrays, prefer for, for...of, or .forEach() for more predictable behavior. The For Of Loop The JavaScript for of statement loops through the values of an iterable object. It lets you loop over iterable data structures such as Arrays, Strings, Maps, NodeLists, and more: Syntax for (variable of iterable) { // code block to be executed } variable - For every iteration the value of the next property is assigned to the variable. Variable can be declared with const, let, or var. iterable - An object that has iterable properties. ✅ Example with Array const colors = ["red", "green", "blue"]; for (let color of colors) { console.log(color); }

    Output red green blue --------------------------------------------------------------------------------- ✅ Example with String const name = "Lakshmi"; for (let char of name) { console.log(char); }

    Output L a k s h m i --------------------------------------------------------------------------------- ✅ Example with Map const userMap = new Map([ ["name", "Rithwik Sai"], ["role", "Student"], ["location", "America"] ]);

    for (let [key, value] of userMap) { console.log(`${key}: ${value}`); }

    Output name : Rithwik Sai role : Student location : America --------------------------------------------------------------------------------- ✅ Example with Set A Set is a collection of unique values. const techStack = new Set(["Docker", "Kubernetes", "Terraform", "Azure"]); for (let tech of techStack) { console.log(tech); }

    Output Docker Kubernetes Terraform Azure The While Loop The while loop in JavaScript runs as long as the given condition is true. It’s useful when you don’t know ahead of time how many times the loop should run. Syntax while (condition) { // code block to be executed }

    Example let count = 1; while (count <= 5) { console.log("Count is:", count); count++; }

    Output Count is: 1 Count is: 2 Count is: 3 Count is: 4 Count is: 5

    ⚠️ Important Notes: • The loop will continue until the condition becomes false. • Be sure to update your condition inside the loop, or you’ll get an infinite loop. Infinite Loop Example (⚠️ Avoid This!) while (true) { // This runs forever unless a break is used console.log("Still running..."); break; // used to stop the infinite loop } The Do While Loop The do...while loop in JavaScript is similar to a while loop, but it runs the code block at least once, even if the condition is false from the beginning. Syntax do { // code block to execute } while (condition);

    Example let count = 1; do { console.log("Count is:", count); count++; } while (count <= 5);

    Output Count is: 1 Count is: 2 Count is: 3 Count is: 4 Count is: 5 =============================================================

    JavaScript Use Strict


    📌 What is "use strict" in JavaScript?

    "use strict" is a directive introduced in ECMAScript 5 (ES5) that enables Strict Mode.

    It helps you write secure and error-free code by changing the way JavaScript works behind

    the scenes.

    Syntax

    "use strict";

    ✅ Where to Use It?

    You can use it in two ways:

    1. Globally (for the entire script):

    "use strict";
    // Entire script runs in strict mode    

    2. Locally (within a function):

    function myFunction() {

    "use strict";

    // Only this function runs in strict mode

    }


    🚫 What Problems Does Strict Mode Catch?

    Here are key features and restrictions of strict mode:


    🔹 1. Prevents usage of undeclared variables

    "use strict";
    x = 10; // ❌ ReferenceError: x is not defined   

    🔹 2. Makes assignments to read-only properties throw errors

    Example

    "use strict";

    const obj = {};

    Object.defineProperty(obj, "prop", { value: 10, writable: false });

    obj.prop = 20; // ❌ TypeError: Cannot assign to read only property


    🔹 3. Eliminates this coercion to global object

    Example

    "use strict";

    function showThis() {

    console.log(this); // ❌ undefined, not the global object

    }

    showThis();

    🔹 4. Disallows duplicate parameter names

    Example

    "use strict";
    function demo(a, a) { } // ❌ SyntaxError: Duplicate parameter name not allowed 

    🔹 5. Reserved keywords are not allowed

    Strict mode reserves some future keywords like implements, interface, let, package, private,

    protected, public, static, and yield.

    Example

    "use strict";
    let package = 5; // ❌ SyntaxError 

    🔹 6. Silent errors become visible

    JavaScript sometimes fails silently. In strict mode, these are converted into throwing errors,

    which is better for debugging.


    🔹 7. Secures eval()

    In strict mode, eval() doesn't create variables in the surrounding scope.

    Example

    "use strict";

    eval("var a = 5;");

    console.log(a); // ❌ ReferenceError: a is not defined


    ✅ Benefits of Using "use strict":

    • Helps catch bugs early
    • Prevents accidental global variables

    • Improves performance in some engines

    • Makes your code future-proof

    • Enforces better coding practices

      ⚠️ Important Notes:

    • "use strict" must be the first statement in a script or function to work.


    ========================================================================

    ========================================================================

    JavaScript Objects

    Real Life Objects

    In real life, objects are things like: houses, cars, people, animals, or any other subjects.

    Object Properties

    A real life car has properties like weight and color:

    car.name = Fiat, car.model = 500, car.weight = 850kg, car.color = white.

    Car objects have the same properties, but the values differ from car to car.


    Object Methods

    A real life car has methods like start and stop:

    car.start(), car.drive(), car.brake(), car.stop().

    Car objects have the same methods, but the methods are performed at different times.

    JavaScript Variables

    JavaScript variables are containers for data values.

    This code assigns a simple value (Fiat) to a variable named car:

    Example

    let car = "Fiat";

    JavaScript Objects

    Objects are variables too. But objects can contain many values.

    This code assigns many values (Fiat, 500, white) to an object named car:

    Example

    const car = {type:"Fiat", model:"500", color:"white"};

    Note:

    It is a common practice to declare objects with the const keyword.

    JavaScript Object Definition

    How to Define a JavaScript Object

    • Using an Object Literal
    • Using the new Keyword
    • Using an Object Constructor

    JavaScript Object Literal

    An object literal is a list of name:value pairs inside curly braces {}.

    {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"}

    Note:

    • name:value pairs are also called key:value pairs.
    • object literals are also called object initializers.

    Creating a JavaScript Object

    This example creates an empty JavaScript object, and then adds 4 properties:

    // Create an Object
    const person = {};

    // Add Properties
    person.firstName = "John";
    person.lastName = "Doe";
    person.age = 50;
    person.eyeColor = "blue";

    -------------------------------

    Using the new Keyword

    This example create a new JavaScript object using new Object(), and then adds 4 properties:

    Example

    // Create an Object
    const person = new Object();

    // Add Properties
    person.firstName = "John";
    person.lastName = "Doe";
    person.age = 50;
    person.eyeColor = "blue";

    Note:

    The examples above do exactly the same.

    But, there is no need to use new Object().

    For readability, simplicity and execution speed, use the object literal method.

    Object Properties

    The named values, in JavaScript objects, are called properties.

    PropertyValue
    firstNameJohn
    lastNameDoe
    age50
    eyeColorblue


    JavaScript Object Methods

    Methods are actions that can be performed on objects.

    Methods are function definitions stored as property values.

    Example

    const person = {
      firstName: "John",
      lastName : "Doe",
      id       : 5566,
      fullName : function() {
        return this.firstName + " " + this.lastName;
      }
    };

    In the example above, this refers to the person object:

    this.firstName means the firstName property of person.

    this.lastName means the lastName property of person.


    In JavaScript, Objects are King.

    If you Understand Objects, you Understand JavaScript.

    Objects are containers for Properties and Methods.

    Properties are named Values.

    Methods are Functions stored as Properties.

    Properties can be primitive values, functions, or even other objects.

    In JavaScript, almost "everything" is an object.

    • Objects are objects
    • Maths are objects
    • Functions are objects
    • Dates are objects
    • Arrays are objects
    • Maps are objects
    • Sets are objects

    All JavaScript values, except primitives, are objects.


    JavaScript Primitives

    primitive value is a value that has no properties or methods.

    3.14 is a primitive value

    primitive data type is data that has a primitive value.

    JavaScript defines 7 types of primitive data types:

    • string
    • number
    • boolean
    • null
    • undefined
    • symbol
    • bigint

    Immutable

    Primitive values are immutable (they are hardcoded and cannot be changed).

    if x = 3.14, you can change the value of x, but you cannot change the value of 3.14.

    ValueTypeComment
    "Hello"string"Hello" is always "Hello"
    3.14number3.14 is always 3.14
    truebooleantrue is always true
    falsebooleanfalse is always false
    nullnull (object)null is always null
    undefinedundefinedundefined is always undefined


    JavaScript Objects are Mutable

    Objects are mutable: They are addressed by reference, not by value.

    If person is an object, the following statement will not create a copy of person:

    const x = person;

    The object x is not a copy of person. The object x is person.

    The object x and the object person share the same memory address.

    Any changes to x will also change person:

    Example

    //Create an Object
    const person = {
      firstName:"John",
      lastName:"Doe",
      age:50, eyeColor:"blue"
    }

    // Try to create a copy
    const x = person;

    // This will change age in person:
    x.age = 10;


    JavaScript Object Properties

    • An Object is an Unordered Collection of Properties
    • Properties are the most important part of JavaScript objects.
    • Properties can be changed, added, deleted, and some are read only.


    Accessing JavaScript Properties

    The syntax for accessing the property of an object is:

    // objectName.property
    let age = person.age;

    or

    //objectName["property"]
    let age = person["age"];

    or

    //objectName[expression]
    let age = person[x];


    Adding New Properties

    You can add new properties to an existing object by simply giving it a value:

    Example

    person.nationality = "English";

    Deleting Properties

    The delete keyword deletes a property from an object:

    Example

    const person = {
      firstName: "John",
      lastName: "Doe",
      age: 50,
      eyeColor: "blue"
    };

    delete person.age;

    output

    const person = {
      firstName: "John",
      lastName: "Doe",
      age: 50,
      eyeColor: "blue"
    };


    Note:

    The delete keyword deletes both the value of the property and the property itself.

    After deletion, the property cannot be used before it is added back again.

    Nested Objects

    Property values in an object can be other objects:

    Example

    myObj = {
      name:"John",
      age:30,
      myCars: {
        car1:"Ford",
        car2:"BMW",
        car3:"Fiat"
      }
    }

    You can access nested objects using the dot notation or the bracket notation:

    Examples

    myObj.myCars.car2;

    myObj.myCars["car2"];

    JavaScript Object Methods

    Object methods are actions that can be performed on objects.

    A method is a function definition stored as a property value.

    Defining Methods Inside Objects

    A method is simply a function inside an object:

    Examples

    const person = {

    name: 'Alice',

    greet: function() {

    console.log('Hello, ' + this.name);

    }

    };

    person.greet(); 

    🔹 this refers to the object the method belongs to.

    output

    Hello, Alice

    --------------------

    Common Built-in Object Methods

    ------------------

    Defining Shorthand Methods

    Examples

    const car = {

    brand: 'Toyota',

    start() {

    console.log(this.brand + ' engine started.');

    }

    };

    car.start(); 

    🔹 this refers to the object the method belongs to.

    output

    Toyota engine started.


    Accessing Object Methods

    You access an object method with the following syntax:

    objectName.methodName()

    If you invoke the fullName property with (), it will execute as a function:

    Example

    name = person.fullName();

    output

    John Doe

    If you access the fullName property without (), it will return the function definition:

    Example

    name = person.fullName;

    output

    function() { return this.firstName + " " + this.lastName; }


    JavaScript Display Objects

    Some solutions to display JavaScript objects are:

    • Displaying the Object Properties by name
    • Displaying the Object Properties in a Loop
    • Displaying the Object using Object.values()
    • Displaying the Object using JSON.stringify()

    1. Displaying the Object Properties by Name

    Manually accessing and displaying each property:

    Example

    const person = { name: 'Alice', age: 25 };

    document.getElementById("demo").innerHTML =

    "Name: " + person.name + "<br>" +

    "Age: " + person.age;

    2. Displaying the Object Properties in a Loop

    Use a for...in loop to iterate through all properties:

    Example

    const person = { name: 'Alice', age: 25 };

    let text = "";

    for (let key in person) {

    text += key + ": " + person[key] + "<br>";

    }

    document.getElementById("demo").innerHTML = text;

    Note:

    You must use person[key] in the loop.

    person.key will not work (Because key is the loop variable).

    3. Displaying the Object using Object.values()

    Get all values in an array and display them:

    Example

    const person = { name: 'Alice', age: 25 };

    const values = Object.values(person);

    document.getElementById("demo").innerHTML = values.join(", ");

    // Output: Alice, 25

    4. Displaying the Object using JSON.stringify()

    Convert the entire object into a JSON string:

    Example

    const person = { name: 'Alice', age: 25 };

    document.getElementById("demo").innerHTML = JSON.stringify(person);

    // Output: {"name":"Alice","age":25}



    JavaScript Object Constructors

    Object Constructor Functions

    • Sometimes we need to create many objects of the same type.
    • To create an object type we use an object constructor function.
    • It is considered good practice to name constructor functions with an upper-case first letter.

    Object Type Person

    function Person(first, last, age, eye) {
      this.firstName = first;
      this.lastName = last;
      this.age = age;
      this.eyeColor = eye;
    }

    Note:

    • In the constructor function, this has no value.
    • The value of this will become the new object when a new object is created.

    Now we can use new Person() to create many new Person objects:

    Example

    const myFather = new Person("John""Doe"50"blue");
    const myMother = new Person("Sally""Rally"48"green");
    const mySister = new Person("Anna""Rally"18"green");

    const mySelf = new Person("Johnny""Rally"22"green");

    How It Works:

    • The new keyword:

      • Creates a new empty object

      • Sets this to point to that object

      • Returns the new object automatically

    ✅ Adding Methods in Constructor:

    Example

    function Car(brand, model) {

    this.brand = brand;

    this.model = model;

    this.getDetails = function() {

    return this.brand + " " + this.model;

    };

    }

    const car1 = new Car("Toyota", "Corolla");

    console.log(car1.getDetails()); // Output: Toyota Corolla


    You cannot add a new method to an object constructor function.

    This code will produce a TypeError:

    Example

    Person.changeName = function (name) {
      this.lastName = name;
    }

    myMother.changeName("Doe");

     TypeError: myMother.changeName is not a function

    Adding a new method must be done to the constructor function prototype:

    Example

    Person.prototype.changeName = function (name) {
      this.lastName = name;
    }

    myMother.changeName("Doe");

    Note:

    The changeName() function assigns the value of name to the person's lastName property, substituting this with myMother.


    Built-in JavaScript Constructors

    JavaScript has built-in constructors for all native objects:

    new Object()   // A new Object object
    new Array()    // A new Array object
    new Map()      // A new Map object
    new Set()      // A new Set object
    new Date()     // A new Date object
    new RegExp()   // A new RegExp object
    new Function() // A new Function object

    Note:

    The Math() object is not in the list. Math is a global object. The new keyword cannot be used on Math.


    Did You Know?


    Example

    "";           // primitive string
    0;            // primitive number
    false;        // primitive boolean

    {};           // object object
    [];           // array object
    /()/          // regexp object
    function(){}; // function

    ==============================================================

    JavaScript Functions


    🔹 Basics of Functions

    1. What is a Function?

    2. Function Declaration

    3. Function Expression

    4. Calling a Function

    5. Return Statement

    6. Function Parameters vs Arguments

    1. What is a Function?

    Definition:
    A function in JavaScript is a reusable block of code designed to perform a specific task. It can take inputs, process them, and return a result.

    Key Points:

    • Promotes code reusability

    • Helps keep code modular and readable

    • Can accept parameters and return values

    Example

    function greet(name) {

      console.log("Hello, " + name + "!");

    }

    greet("John"); // Output: Hello, John!


    2. Function Declaration

    Definition:
    A function declaration (also called a function statement) defines a named function using the function keyword.

    Key Points:

    • Hoisted to the top of their scope, so they can be called before being declared

    • Best for defining reusable named logic

    Syntax

    function functionName(parameters) {

      // code to execute

    }

    Example

    sayHello(); // Allowed due to hoisting


    function sayHello() {

      console.log("Hello!");

    }


    3. Function Expression

    Definition:
    A function expression is when a function is assigned to a variable.

    Key Points:

    • Not hoisted; cannot be called before it's defined

    • Can be anonymous or named

    Example

    const add = function(a, b) {

      return a + b;

    };


    console.log(add(5, 3)); // Output: 8


    4. Calling a Function

    Definition:
    To call (invoke) a function means to execute the code inside it.

    Key Points:

    • Use parentheses () to call a function

    • You can pass arguments inside the parentheses

    Example

    function greet() {

      console.log("Welcome!");

    }

    greet(); // Output: Welcome!

    With arguments:

    function sum(a, b) {

      console.log(a + b);

    }

    sum(2, 3); // Output: 5

    5. Return Statement

    Definition:
    The return statement ends function execution and specifies a value to be returned to the caller.

    Key Points:

    • After return, function exits immediately

    • Useful when you want to get a result back

    Example

    function multiply(a, b) {

      return a * b;

    }

    const result = multiply(4, 5);

    console.log(result); // Output: 20


    6. Function Parameters vs Arguments

    Definition:

    • Parameters are the named variables in a function definition.

    • Arguments are the actual values passed to the function when it is called.

    Key Points:

    • Parameters are like placeholders.

    • Arguments are real values.

    Example

    function welcome(user) { // 'user' is a parameter

      console.log("Welcome, " + user);

    }

    welcome("Alice"); // "Alice" is an argument

    // Output: Welcome, Alice


    Types of Functions

    1. Anonymous Functions

    2. Named Functions

    3. Arrow Functions (=>)

    4. Immediately Invoked Function Expressions (IIFE)

    5. Generator Functions (function*)

    6. Async Functions (async/await)

    1. Named Functions

    A named function has a name when it's declared and can be reused multiple times.

    Example

    function greet() {

      console.log("Hello, World!");

    }

    greet(); // Output: Hello, World!

    Use case: Good for reusable logic and stack trace readability in debugging.


    2. Anonymous Functions

    Functions without a name. Often used as arguments to other functions or assigned to variables.

    Example

    const sayHi = function() {

      console.log("Hi!");

    };

    sayHi(); // Output: Hi!

    Use case: Useful for passing as callbacks (e.g., in setTimeout, .map() etc.)


    3. Arrow Functions (=>)

    Shorter syntax for writing function expressions. Arrow functions do not bind their own this.

    Example

    const add = (a, b) => a + b;

    console.log(add(5, 3)); // Output: 8

    Multiline syntax:

    const greet = (name) => {

      console.log("Hello, " + name);

    };

    greet("Alex"); // Output: Hello, Alex

    Note: Avoid arrow functions for object methods if you need access to this.


    4. IIFE (Immediately Invoked Function Expression)

    A function that runs immediately after it's defined.

    Example

    (function () {

      console.log("IIFE executed");

    })();

    Or with arrow function:

    (() => {

      console.log("Arrow IIFE executed");

    })();

    Use case: Used to create a private scope and avoid polluting the global namespace.


    5. Generator Functions (function*)

    Special functions that can pause and resume execution using the yield keyword.

    Example

    function* count() {

      yield 1;

      yield 2;

      yield 3;

    }

    const counter = count();

    console.log(counter.next().value); // 1

    console.log(counter.next().value); // 2

    console.log(counter.next().value); // 3

    Use case: Useful for building iterators, managing async flows before async/await.


    6. Async Functions (async/await)

    Used to write asynchronous code in a synchronous style. Always returns a Promise.

    Example

    async function fetchData() {

      return "Data fetched";

    }

    fetchData().then(result => console.log(result)); // Output: Data fetched

    With await:

    function getData() {

      return new Promise(resolve => {

        setTimeout(() => resolve("Data loaded"), 1000);

      });

    }


    async function load() {

      const data = await getData();

      console.log(data); // Output (after 1s): Data loaded

    }

    load();


    Function Concepts

    • First-Class Functions

    • Higher-Order Functions

    • Callback Functions

    • Pure vs Impure Functions

    • Recursive Functions

    • Closures in JavaScript


    1.First-Class Functions

    In JavaScript, functions are first-class citizens. This means functions can:

    1. Be assigned to variables,

    2. Be passed as arguments to other functions,

    3. Be returned from other functions.

    Example:

    // Assigned to a variable
    const greet = function(name) {
      return `Hello, ${name}`;
    };

    // Passed as an argument
    function processGreeting(fn, name) {
      console.log(fn(name));
    }

    processGreeting(greet, "Alice"); // Output: Hello, Alice

    // Returned from another function
    function multiplier(factor) {
      return function(num) {
        return num * factor;
      };
    }

    const double = multiplier(2);
    console.log(double(5)); // Output: 10

    Summary: Functions are treated like any other value (number, string, etc.).

    2.Higher-Order Functions

    A higher-order function is a function that either takes another function as an argument, returns a function, or both.

    In other words: Every higher-order function uses first-class functions, but not all first-class functions are higher-order.

    ✅ Example: 

    function multiply(factor) {
      return function(num) {
        return num * factor;
      };
    }

    const double = multiply(2);
    console.log(double(5)); // Output: 10

    Key Points:

    • Used in array methods (map, filter, reduce)

    • Promotes cleaner and modular code


    3.Callback Functions

    🔸 Explanation:

    A callback function is passed into another function as an argument and executed later.

    ✅ Example: 

    function fetchData(callback) {
      setTimeout(() => {
        callback("Data received");
      }, 1000);
    }

    fetchData(function(data) {
      console.log(data); // Output: Data received
    });

    🔑 Key Points:

    • Used heavily in async programming

    • Can cause "callback hell" if nested deeply (solved with Promises/async-await)


    4. ✅ Pure vs Impure Functions

    🔸 Pure Function:

    • No side effects

    • Given same inputs, always returns same output

    ✅ Example: 

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

    🔸 Impure Function:

    • Has side effects (e.g., modifying global variables, DOM, I/O)

    • May return different outputs for same inputs

    ✅ Example: 

    let count = 0;
    function increment() {
      count++;
      return count;
    }

    🔑 Key Points:

    • Pure functions are predictable and testable

    • Impure functions are common in real-world apps (logging, user input)


    5. ✅ Recursive Functions

    🔸 Explanation:

    A recursive function calls itself until it reaches a base condition.

    ✅ Example: Factorial

    function factorial(n) {
      if (n === 1) return 1;
      return n * factorial(n - 1);
    }

    console.log(factorial(5)); // Output: 120

    🔑 Key Points:

    • Always define a base case to avoid infinite loop

    • Useful for tree structures, nested loops


    6. ✅ Closures in JavaScript

    🔸 Explanation:

    A closure is when a function remembers variables from its lexical scope even after the outer function has finished executing.

    ✅ Example: 

    function outer() {
      let count = 0;
      return function inner() {
        count++;
        console.log(count);
      };
    }

    const counter = outer();
    counter(); // Output: 1
    counter(); // Output: 2

    🔑 Key Points:

    • Inner function "closes over" outer variables
    • Used for data privacy and maintaining state
    • Common in functional patterns and event handlers

    Advanced Function Features

    • Rest Parameters (...args)

    • Spread Operator in Function Calls

    • Function Overloading in JS (workarounds)

    • Currying Functions

    • Memoization


    1. Rest Parameters (...args)

    🔸 Explanation:

    Rest parameters allow a function to accept multiple arguments as an array.

    ✅ Example: 

    function sum(...numbers) {
      return numbers.reduce((total, num) => total + num, 0);
    }

    console.log(sum(1, 2, 3, 4)); // Output: 10

    🔑 Key Points:

    • Gathers remaining arguments into an array
    • Can only be the last parameter
    • Useful when number of arguments is unknown

    2. Spread Operator in Function Calls

    🔸 Explanation:

    The spread operator (...) expands an array into individual elements.

    ✅ Example: 

    const nums = [1, 2, 3];
    console.log(Math.max(...nums)); // Output: 3

    🔑
    Key Points:
    • Opposite of rest parameters
    • Useful for passing arrays into functions or combining arrays

     3. Function Overloading in JS (Workarounds)

    🔸 Explanation:

    JavaScript doesn't support traditional function overloading, but you can simulate it using conditions inside the function.

    ✅ Example: 

    function greet(name, age) {
      if (age !== undefined) {
        return `Hello, ${name}. You are ${age} years old.`;
      } else {
        return `Hello, ${name}.`;
      }
    }

    console.log(greet("Alice"));         // Hello, Alice.
    console.log(greet("Alice", 25));     // Hello, Alice. You are 25 years old.

    🔑 Key Points:

    • Check the number or type of arguments using arguments.length or typeof

    • Simulates overloading behavior


    4. Currying Functions

    🔸 Explanation:
    Currying is transforming a function with multiple arguments into a series of functions each taking one argument.

    ✅ Example: 

    function multiply(a) {
      return function(b) {
        return a * b;
      };
    }

    const double = multiply(2);
    console.log(double(5)); // Output: 10

    🔑 Key Points:
    • Useful for creating reusable functions
    • Helps in function composition and partial application

    5. Memoization

    🔸 Explanation:

    Memoization is a performance optimization that caches function results to avoid recalculating for the same inputs.

    ✅ Example: 

    function memoize(fn) {
      const cache = {};
      return function(arg) {
        if (cache[arg]) {
          console.log("From cache");
          return cache[arg];
        } else {
          const result = fn(arg);
          cache[arg] = result;
          return result;
        }
      };
    }

    const square = memoize(x => x * x);
    console.log(square(4)); // Output: 16
    console.log(square(4)); // Output: 16 (From cache)


    🔑 Key Points:
    • Improves performance for expensive computations
    • Best for pure functions


    Scope & Context
    • Function Scope vs Block Scope
    • Lexical Scope
    • this keyword inside functions
    • Binding this (call, apply, bind)
    • Arrow Functions and this

    1. Function Scope vs Block Scope

    🔸 Function Scope:

    Variables declared with var are scoped to the function in which they are declared.

    ✅ Example: 

    function testVar() {
      if (true) {
        var x = 10;
      }
      console.log(x); // Output: 10 (accessible outside the block)
    }

    🔸 Block Scope:

    Variables declared with let or const are scoped to the block {} in which they are defined.

    ✅ Example: 

    function testLet() {
      if (true) {
        let y = 20;
      }
      console.log(y); // ❌ Error: y is not defined
    }

    🔑 Key Points:

    • Use let and const to avoid scope issues.

    • var leaks outside block—avoid using it unless needed.


    2. Lexical Scope

    🔸 Explanation:

    Lexical scope means that inner functions have access to variables from their outer (parent) function scope.

    ✅ Example: 

    function outer() {
      const outerVar = "I'm outside!";
      
      function inner() {
        console.log(outerVar); // ✅ Accesses outerVar
      }

      inner();
    }

    outer();

    🔑 Key Points:

    • Determined at write-time, not runtime.

    • Enables closures.

    • Scope chain moves outward, not inward.


    3. this Keyword Inside Functions

    🔸 Explanation:

    this refers to the object that is calling the function, but its behavior differs by context.

    🔹 Global Context:

    console.log(this); // In browser: refers to `window` object

    🔹 Inside a regular function:

    function showThis() {
      console.log(this);
    }

    showThis(); // In strict mode: undefined, otherwise window

    🔹 Inside an object method:

    const user = {
      name: "Alice",
      greet() {
        console.log(this.name);
      }
    };

    user.greet(); // Output: Alice

    🔑 Key Points:

    • In non-strict mode, this in global scope refers to window.

    • In object methods, this refers to the object itself.

    • In standalone functions, this may be undefined in strict mode.


    4. Binding this (call, apply, bind)

    🔸 call() – Calls the function with a given this and args (comma-separated)

    function greet(greeting) {
      console.log(`${greeting}, ${this.name}`);
    }

    const person = { name: "John" };
    greet.call(person, "Hello"); // Output: Hello, John

    🔸 apply() – Same as call but arguments are passed as an array

    greet.apply(person, ["Hi"]); // Output: Hi, John

    🔸 bind() – Returns a new function with bound this

    const sayHi = greet.bind(person, "Hey");
    sayHi(); // Output: Hey, John

    🔑 Key Points:

    • call and apply immediately invoke the function.

    • bind returns a new function without invoking it.

    • Used for explicit control over this.


    5. Arrow Functions and this

    🔸 Explanation:

    Arrow functions don’t have their own this. They inherit it from the lexical (outer) scope.

    ✅ Example: 

    const person = {
      name: "Alice",
      greet: function () {
        const arrow = () => {
          console.log(this.name); // Refers to person
        };
        arrow();
      }
    };

    person.greet(); // Output: Alice

    🔹 Compare with regular function:

    const person = {
      name: "Alice",
      greet: function () {
        function regular() {
          console.log(this.name); // ❌ undefined (this is window/global)
        }
        regular();
      }
    };

    person.greet(); // Output: undefined

    🔑 Key Points:

    • Arrow functions do not bind their own this.

    • Use arrow functions in callbacks where you want to preserve outer this.

    📌 Summary Table

    Function Execution

    • Execution Context & Call Stack

    • Hoisting in Functions

    • Event Loop and Function Calls

    • Synchronous vs Asynchronous Execution

    1. Execution Context & Call Stack

    🔸 Execution Context:

    An execution context is the environment in which JavaScript code is evaluated and executed.

    There are three main types:

    • Global Execution Context (GEC): Created when the script first runs.

    • Function Execution Context (FEC): Created whenever a function is invoked.

    • Eval Execution Context: Rarely used (from eval()).

    ✅ Example: 

    var x = 10;

    function outer() {
      var y = 20;
      function inner() {
        var z = 30;
        console.log(x + y + z);
      }
      inner();
    }

    outer(); // Output: 60

    🧠 Behind the scenes:

    • Global Execution Context runs first

    • Then, outer function’s context is pushed to call stack

    • Then, inner function’s context is pushed

    🔑 Key Points:

    • JavaScript runs in a single thread

    • Each function call creates a new execution context

    • Contexts are managed using a Call Stack


    2. Hoisting in Functions

    🔸 Explanation:

    Hoisting means that function declarations and variables (var) are moved to the top of their scope before code execution.

    ✅ Example: 

    greet(); // Output: Hello

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

    Works because greet() is hoisted.

    But for function expressions:

    sayHi(); // ❌ TypeError: sayHi is not a function

    var sayHi = function () {
      console.log("Hi");
    };

    🔑 Key Points:

    • Function declarations are fully hoisted.

    • Function expressions are hoisted as undefined.

    • Always declare functions at the top for clarity.

    3. Event Loop and Function Calls

    🔸 Explanation:

    The event loop handles asynchronous callbacks in the browser or Node.js.

    ✅ Example: 

    console.log("Start");

    setTimeout(() => {
      console.log("Timeout");
    }, 0);

    console.log("End");

    ✅ Output:

    Start
    End
    Timeout

    📌 Why?

    • setTimeout() is asynchronous.

    • It goes to Web APIs, and its callback is queued in the Callback Queue.

    • The event loop pushes it to the Call Stack only when it's empty.

    🔑 Key Points:

    • JavaScript uses a single-threaded, non-blocking event loop.

    • Asynchronous functions (e.g., setTimeout, fetch) are queued and processed after the current call stack is clear.


    4. Synchronous vs Asynchronous Execution

    🔸 Synchronous:

    Code is executed line by line, blocking further execution until the current line finishes.

    ✅ Example: 

    console.log("1");
    console.log("2");
    console.log("3");

    ✅ Output:

    1
    2
    3

    🔸 Asynchronous:

    Code does not wait and allows the next lines to run immediately.

    ✅ Example: 

    console.log("1");

    setTimeout(() => {
      console.log("2");
    }, 1000);

    console.log("3");

    ✅ Output:

    1
    2
    3

    🔑 Key Points:

    📌 Summary Table

    Built-in Function Methods

    • setTimeout and setInterval

    • Function.prototype.bind()

    • Function.prototype.call()

    • Function.prototype.apply()

    • toString(), name, length properties of functions


    1. setTimeout() and setInterval()

    🔸 setTimeout(fn, delay)

    Executes a function once after a delay (in milliseconds).

    ✅ Example: 

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


    🔸 setInterval(fn, delay)

    Executes a function repeatedly at a given interval.

    ✅ Example: 

    let count = 0;
    const interval = setInterval(() => {
      console.log("Interval running", ++count);
      if (count === 3) clearInterval(interval);
    }, 1000);


    🔑 Key Points:
    • Asynchronous functions.
    • Use clearTimeout() and clearInterval() to stop them.


    ✅ 2. Function.prototype.bind()

    🔸
    Explanation:
    Returns a new function with this permanently bound to the provided object.

    Example: 

    const person = { name: "Alice" };

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

    const boundGreet = greet.bind(person);
    boundGreet(); // Output: Hello Alice


    🔑 Key Points:
    • Doesn’t invoke the function immediately.
    • Creates a copy of the function with bound this.


    3. Function.prototype.call()

    🔸 Explanation:

    Calls a function with a specified this value and arguments passed individually.

    Example: 

    function say(greeting, punctuation) {
      console.log(`${greeting}, ${this.name}${punctuation}`);
    }

    const user = { name: "Bob" };
    say.call(user, "Hi", "!"); // Output: Hi, Bob!


    🔑 Key Points:

    • Invokes the function immediately.
    • Arguments are passed one-by-one.


    4. Function.prototype.apply()

    🔸 Explanation:

    Same as call(), but arguments are passed as an array.

    Example: 

    say.apply(user, ["Hello", "."]); // Output: Hello, Bob.


    🔑 Key Points:

    • Useful when you already have arguments in an array or want to spread them.

    5. Function Properties

    🔸 toString()

    Returns the source code of the function as a string.

    Example: 

    function test() {
      return "hello";
    }

    console.log(test.toString());
    // Output: function test() { return "hello"; }


    🔸 name

    Returns the name of the function.

    Example: 

    console.log(test.name); // Output: test


    🔸 length

    Returns the number of expected parameters (not including rest parameters).

    Example: 

    function add(a, b, ...rest) {}
    console.log(add.length); // Output: 2

    📌 Summary Table

    ============================================================


    JavaScript Numbers


    🔢 JavaScript Numbers Basics

    • JavaScript has only one number type: it uses 64-bit floating-point numbers (IEEE 754 format).

      • So, both integers and floats are of the same type.

    Example

    let x = 3.14;    // A number with decimals
    let y = 3;       // A number without decimals

    Number Properties

    • Numbers can be:

      • Positive or negative

      • Integers or floating-point

      • Special values like Infinity, -Infinity, and NaN (Not a Number)

    Example

    let inf = Infinity;

    let notANumber = NaN;


    Adding Numbers and Strings

    WARNING !!

    JavaScript uses the + operator for both addition and concatenation.

    Numbers are added. Strings are concatenated.

    • If you add two numbers, the result will be a number
    • If you add two strings, the result will be a string concatenation
    • If you add a number and a string, the result will be a string concatenation
    • If you add a string and a number, the result will be a string concatenation

    The JavaScript interpreter works from left to right.

    JavaScript will try to convert strings to numbers in all numeric operations:

    • JavaScript will try to convert strings to numbers when dividing
    • JavaScript will try to convert strings to numbers when multiplying
    • JavaScript will try to convert strings to numbers when subtracting
    • JavaScript will NOT convert strings to numbers when adding

    NaN - Not a Number

    NaN is a JavaScript reserved word indicating that a number is not a legal number.

    Trying to do arithmetic with a non-numeric string will result in NaN (Not a Number):

    Example

    let x = 100 / "Apple";

    Output

    NaN

    NaN is a number: typeof NaN returns number
    Infinity is a number: typeof Infinity returns number.

    ⚠️ Edge Cases

    • Dividing by 0 returns Infinity

    • Invalid operations return NaN

    Example

    console.log(1 / 0); // Infinity

    console.log("abc" / 3); // NaN


    🔹 JavaScript Concept: Number.MAX_VALUE + 1 === Number.MAX_VALUE

    In JavaScript, Number.MAX_VALUE is the largest finite number that can be represented — approximately 1.7976931348623157e+308.

    You might expect that adding 1 to the largest number would change its value — but due to how JavaScript handles floating-point precision, it doesn’t.

    At the scale of Number.MAX_VALUE, the number 1 is too small to make any impact. The result is essentially rounded back to Number.MAX_VALUE, because JavaScript can't represent the small change at such a large magnitude.

     Example:

    console.log(Number.MAX_VALUE); // 1.7976931348623157e+308 console.log(Number.MAX_VALUE + 1); // 1.7976931348623157e+308 console.log(Number.MAX_VALUE + 1 === Number.MAX_VALUE); // true
    🧠 Takeaway:Adding a small number like 1 to Number.MAX_VALUE doesn’t change its value due to floating-point precision limits — so the comparison returns true.

    ===================================

    JavaScript Booleans

     JavaScript has a Boolean data type. It can only take the values true or false.

    The Boolean() Function

    When using the Boolean() function, JavaScript coerces the value to either true or false. An empty string ('') is one of JavaScript’s falsy values, meaning it will always convert to false when evaluated in a boolean context.

    You can use the Boolean() function to find out if an expression (or a variable) is true:

    Example

    Boolean(10 > 9)

    Everything With a "Value" is True

    Examples

    100

    3.14

    -15

    "Hello"

    "false"

    7 + 1 + 3.14
    • [] (empty array)

    • {} (empty object)

    • '0' (a string with zero)

    Everything Without a "Value" is False

    Examples

    false

    0 or -0

    "" // empty string

    null

    undefined

    NaN

    0n (BigInt zero)

    ===================================

    JavaScript Comparison and Logical Operators

    Comparison and Logical operators are used to test for true or false.

    🔍 JavaScript Comparison Operators

    🔗 JavaScript Logical Operators

    Used to combine Boolean expressions:


    In JavaScript, the logical OR operator (||) is not limited to
    returning true or false. Instead, it returns the first truthy
    operand it encounters.

    What does this return?

    3 || 'hello'
    Answer:3Explanation:The logical OR (||) checks operands from left to right.It returns the first operand that is truthy, and does not evaluate further once it finds one.Since 3 is a truthy value, JavaScript returns it immediately without even looking at 'hello'.Examples0 || 'hello'             // 'hello' → because 0 is falsy null || 42             // 42 → null is falsy, 42 is truthy '' || 'default'         // 'default' → empty string is falsy false || true          // true

    🧠 Takeaway:

    The || operator in JavaScript returns the first truthy value,

     not necessarily a boolean. This makes it handy for default values

    and fallbacks.


    🔀 Conditional (Ternary) Operator

    JavaScript also contains a conditional operator that assigns a value to a variable based on some condition.

    Syntax

    variablename = (condition) ?  expressionIfTrue : expressionIfFalse;

    It evaluates the condition:

    • If it's true, it runs expressionIfTrue

    • If it's false, it runs expressionIfFalse

    Example

    let age = 20;

    let result = (age >= 18) ? "Adult" : "Minor";

    console.log(result); // "Adult"

    Comparing Different Types

    Comparing data of different types may give unexpected results.

    🔄 Type Coercion in Comparisons

    Loose Equality (==)

    • Tries to convert types before comparing.

    When comparing a string with a number, JavaScript will convert the string to a number when doing the comparison. An empty string converts to 0. A non-numeric string converts to NaN which is always false. 

    In JavaScript, when comparing two strings using relational operators like >, comparison is done lexicographically (i.e., character by character using Unicode values), not numerically.

    So in the expression

    '2' > '12'
    Here's what happens:The first characters of both strings are compared: '2' vs '1'.Since '2' has a higher Unicode value than '1', the comparison returns true.JavaScript does not convert these strings to numbers for relational comparisons.

    🔍 What is Operator Precedence?

    Operator precedence determines which part of an expression is evaluated first when

    multiple operators are used.

    Example

    true || false && false

    This is not evaluated left to right — instead, && has higher precedence than ||. So it’s

    like:

    Example

    true || (false && false)
    🔑 Logical Operators Precedence in Detail


    🧠 Summary:

    • ! has the highest precedence — it runs first.

    • && comes next.

    • Then ||.

    • ?? (Nullish Coalescing) comes just after ||.


    ===================================

    JavaScript Break and Continue

    🛑 break Statement

    🔹 What it does:

    • Exits the loop immediately, even if the loop condition is still true.

    Example

    for (let i = 1; i <= 10; i++) {

    if (i === 5) {

    break; // exits the loop when i is 5

    }

    console.log(i);

    }

    Output

    1

    2

    3

    4

    💡 As soon as i becomes 5, break kicks in and the loop stops.

    ⏭️ continue Statement
    🔹 What it does:
    Skips the current iteration and moves to the next one.

    Example

    for (let i = 1; i <= 5; i++) {

    if (i === 3) {

    continue; // skips number 3

    }

    console.log(i);

    }

    Output

    1

    2

    4

    5

    💡 When i is 3, continue says “skip this one” — the loop keeps going.

    ===================================

    JavaScript Iterables

    Iterables are iterable objects (like Arrays).

    Iterables can be accessed with simple and efficient code.

    Iterables can be iterated over with for..of loops

    The For Of Loop

    The JavaScript for..of statement loops through the elements of an iterable object.

    Syntax

    for (variable of iterable) {
      // code block to be executed
    }

    Iterating

    Iterating is easy to understand.

    It simply means looping over a sequence of elements.

    🔁 Built-in Iterators

    Some things in JavaScript are already "iterable" like:

    • Arrays

    • Strings

    • Maps

    • Sets


    Iterating Over a String

    You can use a for..of loop to iterate over the elements of a string:

    Example

    const name = "W3Schools";

    for (const x of name) {
      // code block to be executed
    }

    output

    W
    3
    S
    c
    h
    o
    o
    l
    s

    Iterating Over an Array

    You can use a for..of loop to iterate over the elements of an Array:

    Example 1

    const letters = ["a","b","c"];

    for (const x of letters) {
      // code block to be executed
    }

    output

    a
    b
    c

    Iterating Over a Set

    You can use a for..of loop to iterate over the elements of a Set:

    Example

    const letters = new Set(["a","b","c"]);

    for (const x of letters) {
      // code block to be executed
    }

    output

    a
    b
    c

    Iterating Over a Map

    You can use a for..of loop to iterate over the elements of a Map:

    Example

    const fruits = new Map([
      ["apples"500],
      ["bananas"300],
      ["oranges"200]
    ]);

    for (const x of fruits) {
      // code block to be executed
    }

    output

    apples,500
    bananas,300
    oranges,200

    --------

    JavaScript Iterators


    🚶‍♀️ What is an Iterator?

    An iterator is an object in JavaScript that lets you go through a list of items one by one.

    Think of it like flipping through the pages of a book, one page at a time.

    🧠 Basic Idea
    • An iterator has a special method called .next().
    • Every time you call .next(), it gives you:
    • The next value in the sequence.
    • A flag called done, which tells you if the list is over.
    • When done: true, it means you’ve reached the end.
    • You can also create your own custom iterators.

    Example

    function myIterator(arr) {

    let index = 0;

    return {

    next: function () {

    if (index < arr.length) {

    return { value: arr[index++], done: false };

    } else {

    return { done: true };

    }

    }

    };

    }

    const numbers = [10, 20, 30];

    const iter = myIterator(numbers);

    console.log(iter.next()); // { value: 10, done: false }

    console.log(iter.next()); // { value: 20, done: false }

    console.log(iter.next()); // { value: 30, done: false }

    console.log(iter.next()); // { done: true }

    An iterator's next() method always returns an object with { value, done }, making it easy to track both the current item and the end of iteration.

    🔄 What is Symbol.iterator?

    Symbol.iterator is a built-in symbol in JavaScript.
    It tells JavaScript how to loop over an object using a for...of loop or other iteration tools (like the spread operator ...).

    📦 Where is it used?

    Any object that wants to be iterable (usable in for...of) must have a method called [Symbol.iterator]().

    That method must return an iterator object, which has a .next() method.

    🔁 Why Symbol.iterator is Cool

    • It makes custom objects work with for...of.

    • It makes objects compatible with ...spread.

    • It gives you full control over how things are iterated.


    Generator

    🔹 What is a Generator in JavaScript?
    A generator is a special type of function in JavaScript that can pause its execution and resume later. This makes it perfect for producing a sequence of values (like an iterable), one at a time.

    Syntax:

    function* generatorFunction() {

    yield "A";

    yield "B";

    yield "C";

    }

    • function* — The asterisk * indicates it's a generator.
    • yield — This keyword is used to pause and return a value.


    🔁 What Does It Return?
    Calling a generator function doesn’t execute it immediately. Instead, it returns a generator object, which is iterable (can be looped using for...of, spread operator, etc.).

    const gen = generatorFunction(); // gen is now a generator object

    console.log(gen.next()); // { value: 'A', done: false }

    console.log(gen.next()); // { value: 'B', done: false }

    console.log(gen.next()); // { value: 'C', done: false }

    console.log(gen.next()); // { value: undefined, done: true }


    🔹 Are Generators Iterables?

    👉 Yes! Generators are iterables.

    They implement the Symbol.iterator method, which makes them usable in:

    • for...of loops

    • Spread syntax (...)

    • Destructuring

    • Array.from()

    ✅ Example using for...of:

    function* countToThree() {

      yield 1;

      yield 2;

      yield 3;

    }


    for (let num of countToThree()) {

      console.log(num);

    }

    ✅ Output

    1

    2

    3

    🔹 When to Use Generators?

    • When you want lazy evaluation (generate data only when needed)

    • To manage asynchronous workflows (in advanced scenarios)

    • When creating custom iterables

    ===================================

    Sets and Set Methods

    JavaScript Sets

    🧺 What is a Set?

    A Set is a special kind of object in JavaScript that lets you store unique values.

    ✅ No duplicates allowed!

    How to Create a Set

    You can create a JavaScript Set by:

    • Passing an array to new Set()
    • Create an empty set and use add() to add values

    The new Set() Method

    Pass an array to the new Set() constructor:

    Example

    // Create a Set
    const letters = new Set(["a","b","c"]);

    ----------------------------------------------------------

    Create a Set and add values:

    Example

    // Create a Set
    const letters = new Set();

    // Add Values to the Set
    letters.add("a");
    letters.add("b");
    letters.add("c");

    ----------------------------------------------------------

    Create a Set and add variables:

    Example

    // Create a Set
    const letters = new Set();

    // Create Variables
    const a = "a";
    const b = "b";
    const c = "c";

    // Add Variables to the Set
    letters.add(a);
    letters.add(b);
    letters.add(c);

    ----------------------------------------------------------

    If you add equal elements, only the first will be saved:

    Example

    letters.add("a");
    letters.add("b");
    letters.add("c");
    letters.add("c");
    letters.add("c");

    output

    The set has 3 values


    🧠 Explanation:
    • A Set only stores unique values.
    • When you try to add 'c' again, it is ignored silently — no error, no warning.
    • The size of the set remains the same.

    ----------------------------------------------------------

    To get the number of elements in a Set, you use the .size property.

    Example

    const mySet = new Set();

    mySet.add("apple");

    mySet.add("banana");

    mySet.add("cherry");

    console.log(mySet.size);

    output


    🧠
    Explanation:
    • .size is like .length for arrays, but it's used with Set and Map.
    • It returns the total number of unique values in the set.


    🎯 Key Features of Sets


    JavaScript Set Methods


    Let’s take this example Set:

    Example

    const mySet = new Set(["apple", "banana", "cherry"]);

    1. entries()

    Returns an iterator of [value, value] pairs.

    Example

    for (let entry of mySet.entries()) {

    console.log(entry);

    }

    output

    [ 'apple', 'apple' ]

    [ 'banana', 'banana' ]

    [ 'cherry', 'cherry' ]

    🔁 It's mainly for compatibility with Map.
    ----------------------------------------------------------

    2. keys()
    Returns an iterator of [value, value] pairs.

    Example

    for (let key of mySet.keys()) {

    console.log(key);

    }

    output

    apple

    banana

    cherry

    ----------------------------------------------------------

    3. values()
    Also returns an iterator of values.
    In Sets, keys() and values() are the same.

    Example

    for (let value of mySet.values()) {

    console.log(value);

    }

    output

    apple

    banana

    cherry

    ---------------------------------------------------------

    4. forEach()

    Runs a function once per value in the Set.

    Example

    mySet.forEach((value) => {

    console.log(value);

    });

    output

    apple

    banana

    cherry

    ---------------------------------------------------------

    5. has(value)

    Checks if a value exists in the Set. Returns true or false.

    Example

    console.log(mySet.has("banana")); // true

    console.log(mySet.has("grape")); // false

    ---------------------------------------------------------

    6. add(value)

    Adds a value to the Set (only if it’s not already there).

    Example

    mySet.add("grape");

    console.log(mySet); // Set(4) { 'apple', 'banana', 'cherry', 'grape' }

    -----------------
    7. delete(value)

    Removes a specific element from a Set

    Example

    const mySet = new Set(["apple", "banana", "cherry"]);


    console.log(mySet); // Set(3) { 'apple', 'banana', 'cherry' }


    // Remove "banana"

    mySet.delete("banana");

    console.log(mySet);

    output

    Set(2) { 'apple', 'cherry' }

    ----------------------------------------------------------

    8. clear()
     Remove all elements from a Set.

    Example

    const mySet = new Set(["apple", "banana", "cherry"]);

    console.log(mySet); // Set(3) { 'apple', 'banana', 'cherry' }

    // Clear all elements from the set

    mySet.clear();

    console.log(mySet);

    output

    Set(0) {}

    🧠 Explanation:

    • clear() removes every element from the Set.

    • After calling it, the Set becomes empty.

    • It does not return the cleared values — just performs the action.


    ✅ Summary Table

    Convert a Set to an Array using Array.from()

    Example

    const mySet = new Set(["apple", "banana", "cherry"]);

    // Convert Set to Array

    const myArray = Array.from(mySet);

    console.log(myArray);        

    console.log(Array.isArray(myArray)); // true

    output

    [ 'apple', 'banana', 'cherry' ]


    🧠 Explanation:
    • Array.from(set) creates a new array that contains all elements from the set.
    • The elements remain in the same order as they were inserted into the set.
    • You now have a regular array, so you can use all array methods like map(), filter(), push(), etc.

    🔹 How can you iterate over a Set in JavaScript?

    To iterate over a Set, the most common and correct way is by using the for...of loop. The Set object is iterable, which means it supports direct looping of its values.

    Example using for...of:

    const mySet = new Set(["apple", "banana", "cherry"]);

    for (let item of mySet) {

      console.log(item);

    }

    Output:

    apple

    banana

    cherry

    🧠 Explanation:

    • The for...of loop retrieves each value from the set in the insertion order.

    • Unlike arrays, a set only stores unique values, and for...of helps process them one by one.

    • You cannot use for...in (which is for object keys) to iterate over a Set.

    • While while or do...while loops can technically be used with iterators, they are not ideal or direct methods for Set iteration.


    🔹 How do you check if an object is a Set in JavaScript?

    The correct and most reliable way is using the instanceof operator

     Example 

    const mySet = new Set();

    console.log(mySet instanceof Set);

    ✅ Output:

    true

    🧠 Explanation:

    • instanceof checks whether an object was created using a particular constructor, in this case, Set.

    • If mySet was created using the Set constructor, mySet instanceof Set returns true.

    • This works even if the Set is empty or contains values.


    🔹 What is the difference between Set and WeakSet?

    One key difference is:

    WeakSet can only store objects, while Set can store any data type (objects, primitives like numbers, strings, etc.).

     Example 

    const set = new Set();

    set.add(1);

    set.add("hello");

    set.add({ name: "John" });

    console.log(set); // Set can store numbers, strings, objects, etc.


    const weakSet = new WeakSet();

    weakSet.add({ name: "Jane" }); // ✅ Works

    // weakSet.add(1);             // ❌ Error: Invalid value used in weak set

    🧠 Explanation:


    📌 Why only objects in WeakSet?

    • WeakSet is designed to allow garbage collection of its items when they are no longer used elsewhere.

    • Primitives like strings and numbers are not garbage-collected in the same way as objects, so WeakSet disallows them.


    ===================================
    Map and Map Methods

    JavaScript Maps

    A Map holds key-value pairs where the keys can be any datatype.

    A Map remembers the original insertion order of the keys.

    A Map is a collection of keyed data items, just like an object. But unlike objects, keys in Maps can be of any data type — including functions, objects, and primitives.

      How to Create a Map

      You can create a JavaScript Map by:

      • Passing an Array to new Map()

    Example

    // Create a Map
    const fruits = new Map();

    Example

    // Create a Map
    const fruits = new Map([
      ["apples"500],
      ["bananas"300],
      ["oranges"200]
    ]);


    🔹 Common Map Methods

    Let’s go through each JavaScript Map method with simple definitions and examples

    🔹 1. set(key, value)

    Adds a new element to the Map or updates the value for an existing key.

    Example

    const map = new Map();

    map.set('name', 'Alice');

    map.set('age', 25);

    console.log(map);

    // Output: Map(2) { 'name' => 'Alice', 'age' => 25 }


    🔹 2. get(key)

    Returns the value associated with the key.

    Example

    console.log(map.get('name')); 

    // Output: Alice

    console.log(map.get('age'));  

    // Output: 25


    🔹 3. has(key)

    Returns true if the Map contains the specified key.

    Example

    console.log(map.has('name')); 

    // Output: true

    console.log(map.has('email')); 

    // Output: false


    🔹 4. delete(key)

    Removes the element associated with the key.

    Example

    map.delete('age');

    console.log(map); 

    // Output: Map(1) { 'name' => 'Alice' }


    🔹 5. clear()

    Removes all elements from the Map.

    Example

    map.clear();

    console.log(map); 

    // Output: Map(0) {}


    🔹 6. size

    Returns the number of key/value pairs in the Map.

    Example

    const newMap = new Map();

    newMap.set('a', 1);

    newMap.set('b', 2);


    console.log(newMap.size); 

    // Output: 2


    🔹 7.keys()

    Returns the number of key/value pairs in the Map.

    Example

    // Create a new Map

    const myMap = new Map();


    // Add some key-value pairs

    myMap.set('name', 'John');

    myMap.set('age', 30);

    myMap.set('country', 'USA');


    // Get the iterator of all keys

    const keysIterator = myMap.keys();


    // Iterate through the keys

    for (const key of keysIterator) {

      console.log(key);

    }


    Output

    name

     age

     country

    In JavaScript, the Map object has a method called keys() that returns a new Iterator object that contains all the keys in the Map in the order of their insertion. The keys() method does not return an array of keys directly, but rather an iterator, which you can loop over to access the keys.

    Maps are Objects

    typeof returns object

    instanceof Map returns true


    🔹 Map.forEach(callbackFn)

    The forEach() method executes a callback function once for each key-value pair in the Map, in insertion order.

    🔸 Syntax:

    map.forEach((value, key, map) => {

    // your logic here

    });

    • value – The value of the current element

    • key – The key of the current element

    • map – The entire Map object (optional)

    Example:

    const studentScores = new Map();

    studentScores.set('Alice', 85);

    studentScores.set('Bob', 92);

    studentScores.set('Charlie', 78);

    studentScores.forEach((score, name) => {

    console.log(`${name} scored ${score}`);

    });

    🔸 Output:

    Alice scored 85

    Bob scored 92

    Charlie scored 78


    ===================================================================

    Classes and Inheritance

    JavaScript Classes 

    Use the keyword class to create a class.

    Always add a method named constructor():

    Syntax

    class ClassName {
      constructor() { ... }
    }

    Example

    class Car {
      constructor(name, year) {
        this.name = name;
        this.year = year;
      }
    }

    The example above creates a class named "Car".

    The class has two initial properties: "name" and "year".


    A JavaScript class is not an object.

    It is a template for JavaScript objects.


    Using a Class

    When you have a class, you can use the class to create objects:

    Example

    const myCar1 = new Car("Ford"2014);
    const myCar2 = new Car("Audi"2019);

    The example above uses the Car class to create two Car objects.

    The constructor method is called automatically when a new object is created.

    The Constructor Method

    The constructor method is a special method:

    • It has to have the exact name "constructor"
    • It is executed automatically when a new object is created
    • It is used to initialize object properties

    If you do not define a constructor method, JavaScript will add an empty constructor method.


    Class Methods

    Class methods are created with the same syntax as object methods.

    Use the keyword class to create a class.

    Always add a constructor() method.

    Then add any number of methods.

    Syntax

    class ClassName {
      constructor() { ... }
      method_1() { ... }
      method_2() { ... }
      method_3() { ... }
    }


    Create a Class method named "age", that returns the Car age:

    Example

    class Car {
      constructor(name, year) {
        this.name = name;
        this.year = year;
      }
      age() {
        const date = new Date();
        return date.getFullYear() - this.year;
      }
    }

    const myCar = new Car("Ford"2014);
    console.log(`My car is ${myCar.age()} years old.`);

    Output

    My car is 11 years old.

    ----------------------------------------------

    JavaScript Class Inheritance


    In JavaScript, you can define multiple classes in a single file, and one class can inherit from another using the extends keyword.

    A class created with a class inheritance inherits all the methods from another class:

    Example: Two Classes with Inheritance in One File

    // Base class

    class Animal {

    constructor(name) {

    this.name = name;

    }

    speak() {

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

    }

    }

    // Derived class

    class Dog extends Animal {

    speak() {

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

    }

    }

    // Using the classes

    const dog = new Dog("Buddy");

    dog.speak(); 

     Output:

     Buddy barks.

    🔍 Key Points:
    • You can define as many classes as you want in a single file.
    • Use extends to create a subclass.
    • Use super() inside the constructor of the subclass to call the parent class constructor.

    Getters and Setters

    In JavaScript, getters and setters are special methods that allow you to access and modify object properties as if they were regular fields, while still using logic behind the scenes.

    To add getters and setters in the class, use the get and set keywords.

    Syntax for Getters and Setters

    class Person {

    constructor(name) {

    this._name = name; // convention: underscore for private-like property

    }

    // Getter

    get name() {

    return this._name;

    }

    // Setter

    set name(newName) {

    if (newName.length < 2) {

    console.log("Name too short.");

    } else {

    this._name = newName;

    }

    }

    }

    Using the Getter and Setter

    const p = new Person("Alice");

    console.log(p.name); // Uses getter → "Alice"

    p.name = "Bo"; // Uses setter → Valid, sets name to "Bo"

    console.log(p.name); // → "Bo"

    p.name = "A"; // Too short → Setter shows warning, name remains unchanged


    Hoisting


    In JavaScript, class declarations are not hoisted the same way as function declarations.

    🚫 Class Declarations Are Not Hoisted

    If you try to use a class before it's declared, you’ll get a ReferenceError.


     Example: Using a class before declaration (will fail)

    const user = new User("Alice"); // ❌ ReferenceError: Cannot access 'User' before initialization

    class User {

    constructor(name) {

    this.name = name;

    }

    }

    Even though this looks similar to function hoisting, classes behave differently.

    Function Declaration Hoisting (for comparison)

    greet(); // ✅ Works, because function declarations are hoisted

    function greet() {

    console.log("Hello!");

    }


    🔍 Why Aren't Classes Hoisted?

    • Classes are hoisted technically, but they’re in a temporal dead zone (TDZ) — like let and const.

    • You cannot use the class until the interpreter has evaluated the class declaration.


    ✅ Best Practice

    Always define classes before you use them to avoid errors and confusion.

    ===================================

    JavaScript Static Methods

    In JavaScript, static methods are defined using the static keyword inside a class. These methods belong to the class itself, not to instances of the class.

    Syntax: Static Method

    class MathHelper {

    static add(a, b) {

    return a + b;

    }

    }


    🔍 How to Call Static Methods

    console.log(MathHelper.add(5, 3)); // ✅ 8

    • You call it on the class, not on an object instance.

    • Trying to call it from an instance will cause an error:

    const obj = new MathHelper();

    console.log(obj.add(2, 3)); // ❌ TypeError: obj.add is not a function


    📌 Use Cases for Static Methods
    • Utility/helper methods (e.g., Math.max())
    • Factory methods (e.g., Array.from())
    • Operations that don’t depend on instance state

    🧠Static Block (ES2022+)

    You can also use 

    static initialization blocks:

    class Example {

    static info = "Loading...";

    static {

    this.info = "Initialized!";

    }

    }

    Output

    console.log(Example.info); // "Initialized!"


    📌 Can Static Methods Be Inherited in JavaScript?

    In JavaScript, the concept of static methods is quite similar to other object-oriented languages. But many developers wonder:
    Can static methods be inherited in JavaScript?
    The answer is: Yes — subclasses do inherit static methods from their parent classes.

    What Are Static Methods?
    Static methods are defined on the class itself, not on the instances.
    They are called directly on the class, not on objects created from the class.

    Example

    class Animal {

      static info() {

        console.log("Animals are multicellular organisms.");

      }

    }

    Calling Animal.info() works, but calling it on an instance like new Animal().info() will result in an error.

    🔗 Inheritance of Static Methods

    When you use extends to create a subclass, the subclass automatically inherits the static methods of the parent class.

    Example

    class Animal {

      static info() {

        console.log("Animals are multicellular organisms.");

      }

    }


    class Dog extends Animal {}


    // Calling static method from subclass

    Dog.info(); // Output: Animals are multicellular organisms.


    Even though we didn't define the info() method in the Dog class, it works because it's inherited from Animal.


    📌 What's the Difference Between Class and Constructor Function in JavaScript?

    In JavaScript, both classes and constructor functions are used to create objects and set up inheritance. However, there are important differences in how they behave, especially regarding the use of the new keyword.

    Explanation:

    🔹 Constructor Function:

    • A regular function intended to be used with the new keyword.

    • If you forget to use new, it still runs but may cause bugs (because this might refer to window or be undefined in strict mode).

    Example

    function Person(name) {

      this.name = name;

    }


    const p1 = new Person("Alice");  // ✅ Works correctly

    const p2 = Person("Bob");        // ⚠️ Wrong usage — no error, but `this` may be incorrect

    🔹 Class:

    • Introduced in ES6 as syntactic sugar over constructor functions.

    • Always requires new to instantiate — if you forget new, JavaScript throws a TypeError.

    Example

    class Person {

      constructor(name) {

        this.name = name;

      }

    }


    const p1 = new Person("Alice");  // ✅ Works

    const p2 = Person("Bob");        // ❌ TypeError: Class constructor Person cannot be invoked without 'new'

    🔑 Key Takeaway:

    JavaScript classes enforce the use of new, whereas constructor functions do not — making classes safer and more predictable.

    ===================================

    JavaScript Callbacks

    "I will call back later!"

    A callback is a function passed as an argument to another function.

    This technique allows a function to call another function.

    A callback function can run after another function has finished.


    Function Sequence

    JavaScript functions are executed in the sequence they are called. Not in the sequence they are defined.

    This example will end up displaying "Goodbye":

    Example

    function myFirst() {
      myDisplayer("Hello");
    }

    function mySecond() {
      myDisplayer("Goodbye");
    }

    myFirst();
    mySecond();

    Output

    Hello
    Goodbye
    ---------
    This example will end up displaying "Hello":

    Example

    function myFirst() {
      myDisplayer("Hello");
    }

    function mySecond() {
      myDisplayer("Goodbye");
    }

    mySecond();
    myFirst();

    Output

    Goodbye
    Hello

    Sequence Control

    Sometimes you would like to have better control over when to execute a function.

    Suppose you want to do a calculation, and then display the result.

    You could call a calculator function (myCalculator), save the result, and then call another function (myDisplayer) to display the result:

    Example 1

    function myDisplayer(some) {

    console.log(some);

    }

    function myCalculator(num1, num2) {

    let sum = num1 + num2;

    return sum;

    }

    let result = myCalculator(5, 5);

    myDisplayer(result);

    Output:

    10


    You could call a calculator function (myCalculator), and let the calculator function call the display function (myDisplayer):

    Example 2

    function myDisplayer(some) {
      console.log(some);
    }

    function myCalculator(num1, num2) {
      let sum = num1 + num2;
      myDisplayer(sum);
    }

    myCalculator(55);

    ✅ Output:

    10

    The problem with the example 1 above, is that you have to call two functions to display the result.

    The problem with the example 2, is that you cannot prevent the calculator function from displaying the result.

    Now it is time to bring in a callback.

    Callbacks

    Using a callback, you could call the calculator function (myCalculator) with a callback (myCallback), and let the calculator function run the callback after the calculation is finished:

    Example

    function myDisplayer(some) {
     console.log(some);
    }

    function myCalculator(num1, num2, myCallback) {
      let sum = num1 + num2;
      myCallback(sum);
    }

    myCalculator(55, myDisplayer);

    ✅ Output:

    10

    In the example above, myDisplayer is a called a callback function.

    It is passed to myCalculator() as an argument.

    Note

    When you pass a function as an argument, remember not to use parenthesis.

    Right: myCalculator(5, 5, myDisplayer);

    Wrong: myCalculator(5, 5, myDisplayer());


    🧠 Why/When Use Callbacks?
    • Asynchronous behavior: like waiting for a file read, HTTP request, or timeout.
    • Customization: you can change behavior by passing different functions.
    • Decoupling logic: makes code modular and reusable.
    • Where callbacks really shine are in asynchronous functions, where one function has to wait for another function (like waiting for a file to load).

    ===================================

    Asynchronous JavaScript

    "I will finish later!"

    Functions running in parallel with other functions are called asynchronous

    A good example is JavaScript setTimeout()


    🔹 1. What is Asynchronous JavaScript?

    Asynchronous JavaScript means not waiting for tasks (like API calls, timers, file reading, etc.) to finish before moving on to the next line.
    JavaScript runs in a single thread, so async code helps:
    Keep the page responsive
    Avoid blocking operations (e.g., waiting for a server response)



    In the real world, callbacks are most often used with asynchronous functions.

    A typical example is JavaScript setTimeout().


    Waiting for a Timeout

    When using the JavaScript function setTimeout(), you can specify a callback function to be executed on time-out:

    Example

    setTimeout(myFunction, 3000);

    function myFunction() {
     console.log("I love You !!");
    }

    In the example above, myFunction is used as a callback.

    myFunction is passed to setTimeout() as an argument.

    3000 is the number of milliseconds before time-out, so myFunction() will be called after 3 seconds.

    Note

    When you pass a function as an argument, remember not to use parenthesis.

    Right: setTimeout(myFunction, 3000);

    Wrong: setTimeout(myFunction(), 3000);

    Instead of passing the name of a function as an argument to another function, you can always pass a whole function instead:

    Example

    setTimeout(function() { myFunction("I love You !!!"); }, 3000);

    function myFunction(value) {
      console.log(value);
    }

    In the example above, function(){ myFunction("I love You !!!"); } is used as a callback. It is a complete function. The complete function is passed to setTimeout() as an argument.

    3000 is the number of milliseconds before time-out, so myFunction() will be called after 3 seconds.

    Waiting for Intervals:

    When using the JavaScript function setInterval(), you can specify a callback function to be executed for each interval:

    Example

    setInterval(myFunction, 1000);

    function myFunction() {
      let d = new Date();
      console.log(
      d.getHours() + ":" +
      d.getMinutes() + ":" +
      d.getSeconds());
    }

    In the example above, myFunction is used as a callback.

    myFunction is passed to setInterval() as an argument.

    1000 is the number of milliseconds between intervals, so myFunction() will be called every second.

    Callback Alternatives

    With asynchronous programming, JavaScript programs can start long-running tasks, and continue running other tasks in parallel.

    But, asynchronus programmes are difficult to write and difficult to debug.

    Because of this, most modern asynchronous JavaScript methods don't use callbacks. Instead, in JavaScript, asynchronous programming is solved using Promises instead.

    Key Concepts in Asynchronous JavaScript
    A. Callbacks
    • A function passed into another function to run after a task finishes.
    • Problem: Callback Hell (nested, messy code)

    B. Promises (introduced in ES6)

    • A Promise represents a future value (resolved or rejected).

    C. async/await (introduced in ES2017)

    • A cleaner way to write asynchronous code using Promises.
    • await pauses the function until the Promise is resolved.

    ===================================

    JavaScript Promises

    "I Promise a Result!"

    "Producing code" is code that can take some time

    "Consuming code" is code that must wait for the result

    A Promise is an Object that links Producing code and Consuming code


    🔷 1. What is a Promise?

    A Promise in JavaScript is an object that represents the eventual result (or failure) of an asynchronous operation.

    Think of it like a “promise” to return something in the future.

    🔷 2. Why Use Promises?

    • To avoid callback hell

    • To handle asynchronous code cleanly

    • To make code more readable, maintainable, and error-resilient

    🔷 3. Promise Lifecycle (States)/Promise Object Properties

    The Promise object supports two properties: state and result.

    A Promise has three states:

    You cannot access the Promise properties state and result[undefined, a result value, an error object].

    You must use a Promise method to handle promises.


    JavaScript Promise Object

    A Promise contains both the producing code and calls to the consuming code:

    Promise Syntax

    let myPromise = new Promise(function(myResolve, myReject) {
    // "Producing Code" (May take some time)

      myResolve(); // when successful
      myReject();  // when error
    });

    // "Consuming Code" (Must wait for a fulfilled Promise)
    myPromise.then(
      function(value) { /* code if successful */ },
      function(error) { /* code if some error */ }
    );

    When the producing code obtains the result, it should call one of the two callbacks:

    WhenCall
    SuccessmyResolve(result value)
    ErrormyReject(error object)

    Promise.then() takes two arguments, a callback for success and another for failure.

    Both are optional, so you can add a callback for success or failure only.

    🔷 6. Simulate Data Fetch

    Example:

    function fetchData() {

    return new Promise((resolve, reject) => {

    setTimeout(() => {

    resolve("Data fetched!");

    }, 2000);

    });

    }

    fetchData()

    .then(data => console.log(data)) // Success

    .catch(err => console.error(err)); // Failure (if rejected)


    🔷
    7. Chaining Promises

    You can chain multiple .then() calls:

    Example 

    fetchData()

    .then(data => {

    console.log(data);

    return "Processing data...";

    })

    .then(processed => console.log(processed));

    🔷 8. Error Handling with .catch()

    Example 

    new Promise((resolve, reject) => {

    throw new Error("Something went wrong!");

    })

    .catch(error => console.error("Caught:", error.message));


    🔷 9. finally() Method

    Runs after .then() or .catch(), regardless of the result:

    Example 

    fetchData()

    .then(data => console.log(data))

    .catch(err => console.error(err))

    .finally(() => console.log("Done fetching"));


    🔷 11. Promise Utility Methods
    Promise.all([])

    Wait for all promises to resolve.

    Example 

    Promise.all([

    fetchData1(),

    fetchData2()

    ]).then(results => {

    console.log(results); // Array of all results

    });


    Promise.race([])

    Resolves/rejects as soon as the first one does.

    🔷 12. Comparison with Callback
    Callback:

    getData(function(data) {

    processData(data, function(result) {

    console.log(result);

    });

    });


    Promise:

    getData()

    .then(data => processData(data))

    .then(result => console.log(result));

    🔷 13. Best Practices

    ✅ Always return the Promise in functions
    ✅ Handle .catch() to avoid unhandled errors
    ✅ Use finally() to close resources
    ✅ Prefer async/await for cleaner syntax (uses Promises under the hood)


    🔷 14. Summary Table



    ===================================

    JavaScript Async/ Await

    "async and await make promises easier to write"

    async makes a function return a Promise

    await makes a function wait for a Promise


    🔷 1. What is async/await?

    async/await is syntactic sugar introduced in ES2017 (ES8) that makes asynchronous code look and behave like synchronous code, making it easier to read and manage.

    ✅ It is built on top of Promises, so you need to understand Promises first.

    🔷 2. Why Use async/await?

    • Cleaner and more readable than .then().catch() chains

    • Error handling is easier with try...catch

    • Works well for complex flows and sequential async operations

    🔷 3. Syntax and Basic Structure

    async Function

    • Declares a function that always returns a Promise

    Example

    async function myFunc() {

    return "Hello";

    }

    myFunc().then(result => console.log(result)); // Output: Hello


    await Expression

    • Pauses execution until the Promise is resolved

    • Can only be used inside async functions

    Example

    async function myFunc() {

    let result = await Promise.resolve("World");

    console.log(result); // Output: World

    }

    myFunc();


    🔷 4. Real-World Example with Delay

    Example

    function fetchData() {

    return new Promise(resolve => {

    setTimeout(() => resolve("Data loaded"), 2000);

    });

    }

    async function displayData() {

    console.log("Fetching...");

    let data = await fetchData();

    console.log(data);

    }

    displayData();

    Output:

    Fetching...

    (Data loads after 2 seconds)

    Data loaded

    🔷 5. Sequential vs Parallel Execution

    🔸 Sequential (one after another)

    Example

    async function getSequentialData() {

    let data1 = await fetchData1();

    let data2 = await fetchData2();

    console.log(data1, data2);

    }

    🔸 Parallel (at the same time)

    Example

    async function getParallelData() {

    let [data1, data2] = await Promise.all([fetchData1(), fetchData2()]);

    console.log(data1, data2);

    }


    🔷 6. Error Handling with try...catch

    Example

    async function getUserData() {

    try {

    let response = await fetch("https://api.example.com/user");

    let data = await response.json();

    console.log(data);

    } catch (error) {

    console.error("Error fetching user:", error);

    }

    }


    🔷 7. Returning Values from Async Functions

    Example

    async function getNumber() {

    return 42;

    }

    getNumber().then(num => console.log(num)); // Output: 42


    🔷 8. await with Non-Promise Values

    If you await a non-promise, JS wraps it in a resolved Promise automatically:

    Example

    async function demo() {

    let value = await 123;

    console.log(value); // Output: 123

    }

    demo();

    🔍 Behind the Scenes

    When you write:

    let value = await 123;
    JavaScript automatically wraps that non-promise value (123) in a resolved Promise, like this:
    let value = await Promise.resolve(123);

    So, even though you didn’t create a Promise, await behaves as if you did.

    This is because:

    🔹 await works with any value.
    🔹 If the value is not a Promise, it becomes Promise.resolve(value) automatically.


    🔷 9. Common Pitfalls

    🔷 10. Summary Table

    🔷 11. Visual Comparison

    ❌ With Promises:

    Example

    fetchData()

    .then(data => {

    return processData(data);

    })

    .then(result => {

    console.log(result);

    })

    .catch(error => {

    console.error(error);

    });

    ✅ With async/await:

    Example

    async function handleData() {

    try {

    const data = await fetchData();

    const result = await processData(data);

    console.log(result);

    } catch (error) {

    console.error(error);

    }

    }

    handleData();





    🎉 Conclusion

    Congratulations! You’ve now explored all the core concepts of JavaScript — from variables and functions to advanced topics like promises, async/await, and callbacks. Whether you're a beginner or someone brushing up on your knowledge, this guide should help solidify your understanding of JavaScript fundamentals.