JavaScript Fundamentals
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.
- 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 definedHere:
xis 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:
ifstatementforloopwhileloop- any
{ }curly braces
{
let x = 10;
console.log(x); // works (inside block)
}
console.log(x); // Error (outside block)Here:
xis 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); // 103. 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); // ShahYou 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:
// undefinedvar is hoisted and initialized with undefined.
console.log(b);
let b = 10;
// ReferenceErrorlet 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
JavaScript Variables Operators
- 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; // 03. 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); // falseDifference 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"); // false4. 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); // true8. String Operator
let first = "Hello";
let second = "World";
console.log(first + " " + second); // Hello World9. 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--); // 610. Nullish Coalescing Operator(??)
let a = null;
console.log(a ?? "Default"); // DefaultImportant
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); // 5Conditional 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
functionkeyword - Has its own
thiscontext - Supports
argumentsobject - 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)
- this keyword
Regular Function
const user = {
name: "Pankti",
greet: function() {
console.log(this.name);
}
};
user.greet(); // PanktiArrow 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(); // PanktiSolution 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
- Add Elements
fruits.push("UK"); // add at end
fruits.unshift("USA"); // add at beginning2. Remove Elements
fruits.pop(); // remove from end
fruits.shift(); // remove from beginning3. Find / Check
fruits.includes("India"); // true/false
fruits.indexOf("UK"); // index or -14. 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);
// 6Example
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 };- 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]
- 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)); // 302.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/awaitmakes 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:
WelcomeAfter clicking:
Welcome to JavaScript DOM!Explanation:
documentrepresents the webpage.getElementById()selects the HTML element.innerTextchanges 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 -
1Common DOM Methods
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
3Why 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.





