Sitemap

JavaScript Fundamentals

12 min readJul 10, 2026

--

What is JavaScript?

JavaScript is a powerful programming language that plays a key role in making websites interactive and dynamic. While HTML is used to structure content and CSS is used to design and style it, JavaScript adds behavior and functionality to web pages. It allows developers to create features like clickable buttons, real-time content updates, animations, pop-ups, and interactive forms. In simple terms, JavaScript is what makes a website respond to user actions instead of just displaying static information. Whether it’s updating content without reloading the page, validating form inputs, or creating engaging user experiences, JavaScript acts as the “brain” of a website, bringing it to life and making it more engaging for users.

JavaScript Variables

Variables in JavaScript are used to store data values

Variables can be declared using var, let, or const.

  1. var keyword

var is a keyword in JavaScript used to declare variables and it is function-scoped and hoisted, allowing redeclaration but can lead to unexpected bugs.

Function-scoped: Function scope means a variable is only accessible inside the function where it is declared.

function test() {
var x = 10;
console.log(x); // works
}
console.log(x); // Error: x is not defined

Here:

  • x is available inside the function
  • but not outside

2. let keyword

let is a keyword in JavaScript used to declare variables and it is Block-scoped and not hoisted to the top, suitable for mutable variables

Block scope means a variable is only accessible inside the { } (block) where it is declared.

A “block” can be:

  • if statement
  • for loop
  • while loop
  • any { } curly braces
{
let x = 10;
console.log(x); // works (inside block)
}
console.log(x); // Error (outside block)

Here:

  • x is available inside the block
  • but not outside

let cannot be redeclared in the SAME scope

let x = 10;
let x = 20; // Error (same scope)
let x = 10;

{
let x = 20; // different scope
console.log(x); // 20
}

console.log(x); // 10

3. const keyword

const is a keyword in JavaScript used to declare variables and it is Block-scoped, immutable bindings that can’t be reassigned, though objects can still be mutated.

  • Redeclaration in Different Scope (Allowed)
{
const x = 10;
console.log(x); // 10
}

const x = 20;
console.log(x); // 20
  • Redeclaration in Same Scope (Error )
const a = 10;
const a = 20; // Error: Identifier 'a' has already been declared
  • Reassignment (Error)
const b = 10;
b = 20; // Error: Assignment to constant variable
  • Object Mutation (Allowed)
const person = {
name: "Pankti"
};

person.name = "Shah"; // allowed
console.log(person.name); // Shah

You can modify object properties, but you cannot reassign the object itself

What is hoisting?

Hoisting is JavaScript’s behavior of processing declarations before the code starts executing. During the creation phase of execution, JavaScript scans the entire scope and allocates memory for variables and functions. As a result, some variables and functions can be referenced before they appear in the source code, although their behavior depends on how they were declared.

console.log(a);
var a = 10;

// Output:
// undefined

var is hoisted and initialized with undefined.

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

// ReferenceError

let and const are hoisted but stay in the Temporal Dead Zone (TDZ) until initialized.

JavaScript Data Types

JavaScript data types define what kind of values a variable can hold and how those values behave in a program

Press enter or click to view image in full size

JavaScript Variables Operators

  1. Arithmetic Operators
let a = 10;
let b = 5;

console.log(a + b); // 15 (Addition)
console.log(a - b); // 5 (Subtraction)
console.log(a * b); // 50 (Multiplication)
console.log(a / b); // 2 (Division)
console.log(a % b); // 0 (Modulus)
console.log(a ** b); // 100000 (Exponentiation)

2. Assignment Operators

let x = 10;

x += 5; // x = x + 5 → 15
x -= 3; // 12
x *= 2; // 24
x /= 4; // 6
x %= 2; // 0

3. Comparison Operators

let a = 10;
let b = "10";

console.log(a == b); // true (value only)
console.log(a === b); // false (value + type)
console.log(a != b); // false
console.log(a !== b); // true
console.log(a > 5); // true
console.log(a < 5); // false
console.log(a >= 10); // true
console.log(a <= 9); // false

Difference Between == and === in JavaScript

  • == (Loose Equality) compares only the values and performs automatic type conversion (type coercion) before comparison.
  • === (Strict Equality) compares both the value and the data type without performing any type conversion.
console.log(5 == "5");   // true
console.log(5 === "5"); // false

4. Logical Operators

let a = true;
let b = false;

console.log(a && b); // false (AND)
console.log(a || b); // true (OR)
console.log(!a); // false (NOT)

5. Bitwise Operators

let a = 5;  // 0101
let b = 1; // 0001

console.log(a & b); // 1 (AND)
console.log(a | b); // 5 (OR)
console.log(a ^ b); // 4 (XOR)
console.log(~a); // -6 (NOT)
console.log(a << 1); // 10 (Left shift)
console.log(a >> 1); // 2 (Right shift)

6. Ternary Operators

let age = 18;

let result = (age >= 18) ? "Adult" : "Minor";
console.log(result);

7. Type Operators

let a = 10;

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

let arr = [1,2,3];
console.log(arr instanceof Array); // true

8. String Operator

let first = "Hello";
let second = "World";

console.log(first + " " + second); // Hello World

9. Increment & Decrement

let a = 5;

console.log(++a); // 6 (pre-increment)
console.log(a++); // 6 (post-increment, then becomes 7)

console.log(--a); // 6
console.log(a--); // 6

10. Nullish Coalescing Operator(??)

let a = null;

console.log(a ?? "Default"); // Default

Important

let x = "1" + "2";
console.log(x);

Answer: “12”

Why ?

Both are strings

operator → concatenates (joins) strings

let y = "5" - "2";
console.log(y);

Answer: 3

“-” operator → converts strings to numbers
Then performs subtraction

“5” → 5
“2” → 2
5–2 = 3

More Examples

console.log("10" + 5); // "105"
console.log("10" - 5); // 5
console.log("10" * 2); // 20
console.log("10" / 2); // 5

Conditional Statements

let age = 18;

if (age >= 18) {
console.log("Adult");
} else {
console.log("Minor");
}

Switch

let day = 1;

switch(day) {
case 1:
console.log("Monday");
break;
default:
console.log("Other day");
}

Loops

// for loop
for (let i = 0; i < 5; i++) {
console.log(i);
}

// while loop
let i = 0;
while (i < 5) {
console.log(i);
i++;
}

Functions

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

// Arrow function
const sum = (a, b) => a + b;

Regular Function

  • Defined using function keyword
  • Has its own this context
  • Supports arguments object
  • Can be used as a constructor (new)
  • Fully hoisted

Arrow Function

  • Introduced in ES6 (=>)
  • Does not have its own this (inherits from parent)
  • Does not have arguments
  • Cannot be used as a constructor
  • Not hoisted like normal function

Practical Differences (Most Important)

  1. this keyword

Regular Function

const user = {
name: "Pankti",
greet: function() {
console.log(this.name);
}
};

user.greet(); // Pankti

Arrow Function

const user = {
name: "Pankti",
greet: () => {
console.log(this.name);
}
};

user.greet(); // undefined ❗

Arrow functions don’t have their own this. They inherit this from their lexical (surrounding) scope. Therefore, inside an object, an arrow function does not bind this to the object itself. If you need this to refer to the object, use a regular function or method shorthand.

Correct Way

Solution 1:

const name = "Pankti";

const user = {
greet: () => {
console.log(name);
}
};

user.greet(); // Pankti

Solution 2:

const user = {
name: "Pankti",
greet: function() {
const inner = () => {
console.log(this.name);
};
inner();
}
};

user.greet(); // Pankti

Arrays

In JavaScript, an array is a global object used to store multiple values in a single variable. It is zero-indexed (the first element is at index 0), dynamically sized (it grows or shrinks as needed), and can hold a mix of different data types like strings, numbers, and objects at the same time

let fruits = ["India", "Germany", "Brazil"];
  • Index starts from 0
  • fruits[0] → "India"

Common Array Methods

  1. Add Elements
fruits.push("UK");   // add at end
fruits.unshift("USA"); // add at beginning

2. Remove Elements

fruits.pop();    // remove from end
fruits.shift(); // remove from beginning

3. Find / Check

fruits.includes("India"); // true/false
fruits.indexOf("UK"); // index or -1

4. Looping Methods

fruits.forEach((item) => {
console.log(item);
});

5. Map ,Filter and Reduce

map

Creates a new array by applying a function to every element of the original array.

let nums = [1, 2, 3];

let doubled = nums.map((n) => n * 2);
// [2, 4, 6]

Filter

Get Shahpankti’s stories in your inbox

Join Medium for free to get updates from this writer.

Creates a new array containing only the elements that meet a condition.

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

let even = nums.filter((n) => n % 2 === 0);
// [2, 4]

Reduce

Reduces an array to a single value by combining its elements.

let nums = [1, 2, 3];

let sum = nums.reduce((acc, curr) => acc + curr, 0);
// 6

Example

Get total salary of users whose age > 25, after increasing their salary by 10%.

const users = [
{ name: "A", age: 22, salary: 2000 },
{ name: "B", age: 28, salary: 3000 },
{ name: "C", age: 30, salary: 4000 },
];

// Step 1: filter (age > 25)
// Step 2: map (increase salary by 10%)
// Step 3: reduce (sum all salaries)

const result = users
.filter(user => user.age > 25)
.map(user => user.salary * 1.1)
.reduce((total, salary) => total + salary, 0);

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

What is the diffrence between for each and map?

  • forEach() is used to iterate over an array and perform an action. It does not return a new array.
  • map() is used to transform each element and returns a new array without changing the original array.

6. Slice vs Splice

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

// slice (does NOT modify original)
arr.slice(1, 3); // [2, 3]

// splice (modifies original)
arr.splice(1, 2); // removes [2, 3]

7. Sort and Reverse

let nums = [5, 2, 9, 1];

// sort (ascending)
nums.sort((a, b) => a - b);
console.log(nums); // [1, 2, 5, 9]

// descending sort
nums.sort((a, b) => b - a);
console.log(nums); // [9, 5, 2, 1]

// reverse
nums.reverse();
console.log(nums); // [9, 5, 2, 1]

8. join() and split()

let words = ["Hello", "World"];

// join (array → string)
let sentence = words.join(" ");
console.log(sentence); // "Hello World"

// split (string → array)
let arr = sentence.split(" ");
console.log(arr); // ["Hello", "World"]

Spread Operator (...)

Definition

The Spread Operator (...) is an ES6 feature that expands (spreads) the elements of an iterable (such as an array or string) or the properties of an object into individual elements. It is commonly used to copy arrays or objects, merge them, and pass multiple values to functions.

In simple words: The spread operator takes all elements or properties from an existing array or object and spreads them into a new array, object, or function call.

Syntax

//array
const newArray = [...oldArray];

//Object
const newObject = { ...oldObject };
  1. Copy an Array
const arr1 = [1, 2, 3];

const arr2 = [...arr1];

console.log(arr2);
//Output
//[1, 2, 3]

2.Add New Elements

const arr1 = [1, 2];

const arr2 = [...arr1, 3, 4];

console.log(arr2);
//output
//[1, 2, 3, 4]

3.Merge Arrays

const frontend = ["HTML", "CSS"];
const backend = ["Node.js", "MongoDB"];

const fullStack = [...frontend, ...backend];

console.log(fullStack);
//output
//["HTML", "CSS", "Node.js", "MongoDB"]

4.Copy an Object

const user = {
name: "Pankti",
age: 21
};

const copy = { ...user };

console.log(copy);

output:

{
name: "Pankti",
age: 21
}

5. Merge Objects

const personal = {
name: "Pankti"
};

const professional = {
role: "Developer"
};

const profile = {
...personal,
...professional
};

console.log(profile);

Output:

{
name: "Pankti",
role: "Developer"
}

Rest Operator (...)

Definition

The rest operator (...) allows a function to accept an indefinite number of arguments by bundling them into a single array, or enables destructuring to pack remaining array elements or object properties. Introduced in ES6, it provides a flexible and dynamic way to handle varied inputs in JavaScript. [1, 2, 3, 4, 5]

Key Uses of the Rest Operator

  • Function Parameters: When used as a function parameter, it must be the last parameter. It collects all extra arguments into an array.
  • Destructuring Arrays: It collects the remaining items in an array after extracting the specified elements.
  • Destructuring Objects: It collects the remaining properties of an object into a new object. [1, 2, 3, 4]
  1. Function Rest Parameter
function calculateSum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}

console.log(calculateSum(1, 2, 3)); // 6
console.log(calculateSum(10, 20)); // 30

2.Array Destructuring

const fruits = ['apple', 'banana', 'cherry', 'date'];
const [first, second, ...remainingFruits] = fruits;

console.log(first); // 'apple'
console.log(remainingFruits); // ['cherry', 'date']

3.Object Destructuring

const user = { name: 'Alice', age: 25, city: 'Vadodara', country: 'India' };
const { name, ...otherDetails } = user;

console.log(name); // 'Alice'
console.log(otherDetails); // { age: 25, city: 'Vadodara', country: 'India' }

Template Literals (Template Strings)

Definition

Template Literals are a feature introduced in ES6 (ECMAScript 2015) that allows you to create strings more easily using backticks ( ) instead of single (' ') or double (" ") quotes. They support string interpolation, multi-line strings, and embedded expressions, making code more readable and easier to maintain.

In simple words: Template literals let you write strings using backticks and directly insert variables or expressions using ${} without string concatenation.

Why Use Template Literals?

Without Template Literals

const name = "Pankti";
const age = 21;

console.log("My name is " + name + " and I am " + age + " years old.");

With Template Literals

const name = "Pankti";
const age = 21;

console.log(`My name is ${name} and I am ${age} years old.`);

Callback Function

Definition

A callback function is a function that is passed as an argument to another function and is executed later when a specific task or operation is completed. Callbacks are commonly used for asynchronous operations such as API requests, file handling, and event handling.

In simple words: A callback is a function that is given to another function to be executed after a task finishes.

function greet(name, callback) {
console.log(`Hello ${name}`);
callback();
}

function sayBye() {
console.log("Goodbye!");
}

greet("Pankti", sayBye);

Output:

Hello Pankti
Goodbye!

Callback Hell

Callback Hell is a situation where multiple callbacks are nested inside one another to perform asynchronous tasks in sequence. This creates deeply nested code that is difficult to read, debug, and maintain.

In simple words: Callback Hell happens when callbacks are nested repeatedly, making the code look like a pyramid and becoming hard to understand.

loginUser(function () {
getProfile(function () {
getPosts(function () {
getComments(function () {
console.log("Done");
});
});
});
});

This is called the Pyramid of Doom.

Problems

Difficult to read,debug,maintain and Hard to handle errors

Promise

Definition

A Promise is an object that represents the eventual completion or failure of an asynchronous operation. Instead of using nested callbacks, promises provide a cleaner and more structured way to handle asynchronous code.

In simple words: A Promise is a placeholder for a value that will be available in the future.

Promise States

  • Pending → Initial state
  • Fulfilled → Operation completed successfully
  • Rejected → Operation failed
const promise = new Promise((resolve, reject) => {

let success = true;

if (success) {
resolve("Data fetched successfully");
} else {
reject("Something went wrong");
}
});

promise
.then(result => console.log(result))
.catch(error => console.log(error));

Async / Await

Definition

async and await are ES8 features that simplify working with Promises by allowing asynchronous code to be written in a synchronous and more readable style.

In simple words: async/await makes asynchronous code easier to read and write without using multiple .then() methods.

function fetchData() {
return new Promise(resolve => {
setTimeout(() => {
resolve("Data Loaded");
}, 2000);
});
}

async function getData() {
const result = await fetchData();
console.log(result);
}

getData();

Error Handling (try, catch, finally)

Definition

Error handling is the process of managing runtime errors without stopping the execution of the program. JavaScript provides the try, catch, and finally statements to handle exceptions gracefully.

In simple words: Error handling prevents your application from crashing when an error occurs.

try

Contains the code that may throw an error.

catch

Handles the error if one occurs.

finally

Executes whether an error occurs or not.

try {
let result = 10 / 0;
console.log(result);
}
catch(error) {
console.log(error.message);
}
finally {
console.log("Execution Finished");
}

DOM (Document Object Model)

Definition

The Document Object Model (DOM) is a programming interface that represents an HTML document as a tree of objects. It allows JavaScript to access, modify, create, and remove HTML elements dynamically.

In simple words: The DOM connects JavaScript with HTML so that web pages can be updated without reloading.

Example: Change Text Content

HTML

<h1 id="heading">Welcome</h1>

<button onclick="changeText()">
Click Me
</button>

JavaScript

function changeText() {
document.getElementById("heading").innerText = "Welcome to JavaScript DOM!";
}

Output

Before clicking:

Welcome

After clicking:

Welcome to JavaScript DOM!

Explanation:

  • document represents the webpage.
  • getElementById() selects the HTML element.
  • innerText changes the displayed text.

Example:Counter App

HTML

<h2 id="count">0</h2>

<button onclick="increase()">
+
</button>

<button onclick="decrease()">
-
</button>

JavaScript

let count = 0;

function increase() {

count++;

document.getElementById("count").innerText = count;
}

function decrease() {

count--;

document.getElementById("count").innerText = count;
}

Output:

0

Click +

1

Click +

2

Click -

1

Common DOM Methods

Press enter or click to view image in full size

Closure

Definition

A Closure is created when an inner function remembers and continues to access the variables of its outer function even after the outer function has finished executing.

In simple words: A closure allows a function to remember variables from the scope where it was created.

function counter() {

let count = 0;

return function () {
count++;
console.log(count);
};
}

const increment = counter();

increment();
increment();
increment();

Output:

1
2
3

Why Closures Are Used

Data privacy,Function factories,Maintaining state,Event handlers

Conclusion

JavaScript is one of the most important programming languages for web development. By understanding its core concepts such as variables, data types, operators, functions, arrays, asynchronous programming, DOM manipulation, and closures, you build a strong foundation for creating interactive and dynamic web applications. Mastering these fundamentals not only improves your problem-solving skills but also prepares you to learn advanced JavaScript frameworks and libraries with confidence. Consistent practice and applying these concepts in real projects are the key to becoming a skilled JavaScript developer.

--

--