Complete JavaScript Guide: From Basics to Advanced

Swarada WareSwarada Ware
11 min read

Introduction

JavaScript is the most popular programming language for web development. It's the backbone of interactive websites, enabling dynamic behavior, real-time updates, and much more. Whether you're building a responsive web app or enhancing a simple HTML page, JavaScript is essential.

Why Learn JavaScript?

  • Used by over 95% of websites

  • Core to front-end development

  • Widely used in back-end (Node.js)

  • Supports mobile, desktop, and game development

  • High demand in the job market

History and Evolution

  • Created by Brendan Eich in 1995

  • Initially developed in 10 days as "Mocha"

  • Standardized by ECMA as ECMAScript (ES)

  • Modern versions: ES6 (2015), ES7, ES8, ..., ESNext

🧭 Table of Contents :-

  • Part 1: JavaScript Basics

  • Part 2: Functions and Scope

  • Part 3: Arrays and Objects

  • Part 4: The DOM and Events

  • Part 5: JavaScript in the Browser

  • Part 6: Asynchronous JavaScript

  • Part 7: ES6+ Features

  • Part 8: Error Handling and Debugging

  • Part 9: JavaScript Best Practices

  • Part 10: Advanced Topics

  • Part 11: Interview Questions & Practice

  • Part 12: Project Ideas

Part 1: JavaScript Basics

1.1 Variables and Data Types

Variable Declarations

var x = 10; // function-scoped
let y = 20; // block-scoped
const z = 30; // constant block-scoped

Data Types

  • Primitive: String, Number, Boolean, Undefined, Null, Symbol, BigInt

  • Non-Primitive: Object, Array, Function

let name = "John"; // string
let age = 25; // number
let isStudent = true; // boolean
let empty = null; // null
let notDefined; // undefined

1.2 Operators

  • Arithmetic: +, -, *, /, %, ++, --

  • Comparison: ==, !=, ===, !==, <, >, <=, >=

  • Logical: &&, ||, !

  • Assignment: =, +=, -=, *=, /=

1.3 Conditional Statements

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

switch (grade) {
  case 'A': console.log("Excellent"); break;
  case 'B': console.log("Good"); break;
  default: console.log("Needs improvement");
}

1.4 Loops

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

while (count < 5) {
  console.log(count);
  count++;
}

do {
  console.log(count);
  count++;
} while (count < 5);

Part 2: Functions and Scope

2.1 Functions

Functions are reusable blocks of code designed to perform a particular task.

Function Declaration

function greet(name) {
  return "Hello, " + name + "!";
}
console.log(greet("john"));

Function Expression

const greet = function(name) {
  return `Hello, ${name}!`;
};
console.log(greet("John"));

IIFE (Immediately Invoked Function Expression)

(function() {
  console.log("IIFE executed");
})();

2.2 Scope and Hoisting

Types of Scope

  • Global Scope: Available everywhere

  • Function Scope: Available only inside the function

  • Block Scope: Available inside {} (introduced with let and const)

let globalVar = "I'm global";
function testScope() {
  let functionVar = "I'm local to function";
  if (true) {
    let blockVar = "I'm block scoped";
    console.log(blockVar);
  }
  console.log(functionVar);
}
console.log(globalVar);

Hoisting

JavaScript hoists function declarations and var declarations to the top of their scope.

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

console.log(b); // ReferenceError
let b = 20;

2.3 Closures

A closure gives you access to an outer function’s scope from an inner function.

function outer() {
  let counter = 0;
  return function inner() {
    counter++;
    return counter;
  };
}
const increment = outer();
console.log(increment()); // 1
console.log(increment()); // 2

Closures are useful for:

  • Data privacy

  • Partial application

  • Event handling

Part 3: Arrays and Objects

3.1 Arrays

Arrays are used to store multiple values in a single variable.

let fruits = ["apple", "banana", "cherry"];
console.log(fruits[1]); // Output: banana

Array Methods

  • push(): Add to the end

  • pop(): Remove from the end

  • shift(): Remove from the beginning

  • unshift(): Add to the beginning

  • indexOf(), includes()

  • slice(), splice()

  • forEach(), map(), filter(), reduce()

fruits.push("mango");
fruits.map(fruit => fruit.toUpperCase());

3.2 Objects

Objects are collections of key-value pairs.

let person = {
  name: "Alice",
  age: 30,
  greet: function() {
    console.log("Hello " + this.name);
  }
};
console.log(person.name); // Alice
person.greet();

Object Methods

  • Object.keys()

  • Object.values()

  • Object.entries()

  • Object.assign()

3.3 Destructuring

Destructuring allows you to unpack values from arrays or properties from objects.

const [a, b] = [1, 2];
const { name, age } = person;
console.log(name, age);

3.4 Nested Objects and Arrays

let user = {
  name: "Bob",
  hobbies: ["reading", "gaming"],
  address: {
    city: "Pune",
    zip: 411001
  }
};
console.log(user.address.city);

Part 4: The DOM and Events

4.1 What is the DOM?

The DOM (Document Object Model) represents the structure of an HTML document as a tree of objects. JavaScript can interact with and manipulate this structure to create dynamic web pages.

4.2 Accessing DOM Elements

document.getElementById("id")
document.querySelector(".class")
document.querySelectorAll("tag")

Example:

const heading = document.getElementById("main-heading");
heading.style.color = "blue";

4.3 Modifying the DOM

heading.textContent = "New Heading";
document.body.style.backgroundColor = "#f0f0f0";

4.4 Event Handling

JavaScript uses events to interact with users (e.g., clicks, input, submit).

const btn = document.getElementById("clickBtn");
btn.addEventListener("click", function() {
  alert("Button clicked!");
});

4.5 Common Events

  • click

  • mouseover, mouseout

  • keydown, keyup

  • submit

  • input

4.6 Event Propagation

  • Bubbling: Event flows from target up to root

  • Capturing: Event flows from root down to target

document.getElementById("child").addEventListener("click", function(e) {
  console.log("Child clicked");
}, true);

Part 5: JavaScript in the Browser

5.1 The window and document Objects

In the browser environment, JavaScript has access to two primary objects:

  • window: Represents the browser window. It’s the global object.

  • document: Represents the HTML document loaded in that window.

console.log(window.innerWidth);
console.log(document.title);

You can omit window. when accessing methods like alert(), prompt(), etc.

alert("Welcome!");

5.2 Dialog Boxes

alert("This is an alert!");
confirm("Are you sure?");
prompt("Enter your name:");

5.3 Timers in JavaScript

Use timers to execute code after a delay or at regular intervals.

setTimeout()

Executes a function once after a delay.

setTimeout(() => {
  console.log("This runs after 2 seconds");
}, 2000);

setInterval()

Executes a function repeatedly at intervals.

let count = 0;
const interval = setInterval(() => {
  count++;
  console.log(count);
  if (count === 5) clearInterval(interval);
}, 1000);

5.4 Browser Storage

Local Storage

Stores data with no expiration.

localStorage.setItem("username", John");
console.log(localStorage.getItem("username"));

Session Storage

Stores data for the session (until tab is closed).

sessionStorage.setItem("sessionName", "Guest");

Cookies

Cookies are small pieces of data stored in the user's browser. They are often used for session management, user preferences, or tracking.

  • Stored as key-value pairs

  • Can have expiration dates

  • Accessible via document.cookie.

document.cookie = "token=abc123; expires=Fri, 31 Dec 2025 23:59:59 GMT";

Reading Cookies

console.log(document.cookie);

Limitations:

  • Limited size (around 4KB)

  • Sent with every HTTP request (can impact performance)

  • Less secure compared to modern storage APIs

Part 6: Asynchronous JavaScript

6.1 What is Asynchronous JavaScript?

JavaScript is single-threaded, but asynchronous operations allow it to perform tasks (like API calls or timers) without blocking the main thread. These tasks are handled via:

  • Callbacks

  • Promises

  • async/await

6.2 Callbacks

A callback is a function passed into another function to run later.

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

fetchData((data) => {
  console.log(data);
});

Downside: Callback hell (nested functions that are hard to read/maintain)

6.3 Promises

A Promise represents a future value.

const fetchData = new Promise((resolve, reject) => {
  let success = true;
  setTimeout(() => {
    success ? resolve("Data fetched") : reject("Error");
  }, 1000);
});

fetchData
  .then((data) => console.log(data))
  .catch((err) => console.error(err));

6.4 Async/Await

Introduced in ES8, async/await is a syntactic feature that makes working with promises easier and more readable. It allows you to write asynchronous code that looks like synchronous code, which is especially helpful in avoiding deeply nested .then() chains.

How it Works:

  • The async keyword is used before a function to make it return a Promise.

  • The await keyword is used to wait for a Promise to resolve or reject before continuing execution.

Syntax:

async function functionName() {
  const result = await somePromiseFunction();
  // Continue execution after the promise resolves
}

Example:

const fetchData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("Data received!");
    }, 1000);
  });
};

async function getData() {
  try {
    console.log("Fetching data...");
    const result = await fetchData();
    console.log(result);
  } catch (error) {
    console.error("Error:", error);
  }
}

getData();

Benefits of async/await:

  • Code looks and behaves like synchronous code

  • Easier error handling using try...catch

  • Better readability and maintainability

Points to Note:

  • await only works inside async functions

  • If a promise is rejected and not caught, it will throw an error

Nested Example:

async function fetchUserData() {
  try {
    const userResponse = await fetch("https://api.example.com/user");
    const userData = await userResponse.json();

    const postsResponse = await fetch(`https://api.example.com/posts?user=${userData.id}`);
    const posts = await postsResponse.json();

    console.log(userData, posts);
  } catch (error) {
    console.error("Failed to fetch user data:", error);
  }
}

fetchUserData();

6.5 Fetch API (Making HTTP Requests)

fetch() is a modern way to make HTTP requests.

fetch("https://api.example.com/data")
  .then((res) => res.json())
  .then((data) => console.log(data))
  .catch((err) => console.error(err));

With async/await:

async function loadData() {
  try {
    const response = await fetch("https://api.example.com/data");
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error("Fetch failed", error);
  }
}
loadData();

Part 7 : ES6+ Features

ECMAScript 2015 (commonly known as ES6) introduced a major update to JavaScript, followed by subsequent updates in ES7, ES8, and beyond. These new features improved readability, performance, and scalability of JavaScript code.

7 . 1 let and const

  • let: Block-scoped variable

  • const: Block-scoped constant (cannot be reassigned)

let name = "Alice";
const age = 25;

7.2 Arrow Functions

Provides a concise way to write function expressions.

const greet = (name) => `Hello, ${name}`;

7.3 Template Literals

Allow embedding expressions into strings using backticks.

const name = "Sam";
console.log(`Welcome, ${name}!`);

7.4 Default Parameters

Specify default values for function parameters.

function multiply(a, b = 2) {
  return a * b;
}

7.5 Destructuring

Extract values from arrays or objects easily.

const [a, b] = [1, 2];
const { title, author } = { title: "JS Guide", author: "You" };

7.6 Spread and Rest Operators

  • Spread: Expands iterable into individual elements

  • Rest: Collects remaining elements into an array

const nums = [1, 2, 3];
const newNums = [...nums, 4]; // spread

function sum(...args) { // rest
  return args.reduce((a, b) => a + b);
}

7.7 Enhanced Object Literals

const name = "Swarada";
const user = {
  name,
  greet() {
    return `Hello, ${this.name}`;
  }
};

7.8 Modules (ESM)

Enable import/export of code across files.

// module.js
export const sayHi = () => "Hi";

// main.js
import { sayHi } from './module.js';
console.log(sayHi());

7.9 Classes

Syntactic sugar over prototypes.

class Animal {
  constructor(name) {
    this.name = name;
  }
  speak() {
    console.log(`${this.name} makes a sound`);
  }
}

class Dog extends Animal {
  speak() {
    console.log(`${this.name} barks`);
  }
}

const dog = new Dog("Buddy");
dog.speak();

7.10 Optional Chaining & Nullish Coalescing (ES2020+)

const user = { profile: { name: "Alice" } };
console.log(user?.profile?.name); // Optional chaining

const username = null;
console.log(username ?? "Guest"); // Nullish coalescing

Part 8: Error Handling and Debugging

8.1 try...catch Statement

Use try...catch to gracefully handle runtime errors.

try {
  let result = riskyFunction();
  console.log(result);
} catch (error) {
  console.error("An error occurred:", error);
}

8.2 finally Block

The finally block always executes, regardless of whether there was an error.

try {
  // Code that may throw
} catch (error) {
  // Handle error
} finally {
  console.log("Cleanup or final step");
}

8.3 Custom Errors using throw

function divide(a, b) {
  if (b === 0) throw new Error("Cannot divide by zero");
  return a / b;
}

8.4 The Error Object

const err = new Error("Something went wrong");
console.log(err.name);  // "Error"
console.log(err.message);  // "Something went wrong"

8.5 Debugging Tips

  • Use console.log() extensively

  • Use browser DevTools (Sources tab, breakpoints)

  • Use debugger; in your code

debugger; // Execution will pause here in DevTools

Part 9: JavaScript Best Practices

9.1 Use const and let Instead of var

Avoid var due to hoisting issues and lack of block scope.

9.2 Keep Functions Small and Focused

Break down logic into small, reusable functions.

9.3 Use Strict Mode

"use strict";

This catches common bugs and prevents the use of undeclared variables.

9.4 Naming Conventions

  • Use camelCase for variables and functions

  • Use PascalCase for classes and constructors

  • Use meaningful names

9.5 Avoid Global Variables

Keep your variables local unless absolutely necessary.

9.6 DRY Principle (Don’t Repeat Yourself)

Abstract repetitive code into functions or modules.

9.7 Comment Wisely

Write comments to explain why (not just what) your code does.

9.8 Optimize Loops and DOM Access

Accessing and modifying the DOM is expensive. Minimize operations inside loops.

9.9 Use Linters and Formatters

Use ESLint, Prettier, or other tools to maintain clean, consistent code.

9.10 Avoid Callback Hell

Use async/await or promises to manage asynchronous code clearly.

0
Subscribe to my newsletter

Read articles from Swarada Ware directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Swarada Ware
Swarada Ware