Skip to content

Module 05 — Basic JavaScript & DOM Manipulation


1. What is it?

JavaScript is the high-level, interpreted (just-in-time compiled), multi-paradigm programming language of the World Wide Web.

Standardized as ECMAScript (ECMA-262) by the TC39 committee, JavaScript is the dynamic runtime engine that transforms static HTML and CSS documents into interactive, reactive, and programmable web applications directly inside the browser.


2. Why do we use it?

While HTML establishes content structure and CSS controls visual presentation, neither language possesses computational capabilities:

  • HTML cannot calculate a shopping cart subtotal based on user item quantities.
  • CSS cannot fetch live real-time stock prices or weather data from a remote server without reloading the page.
  • HTML/CSS cannot store user session state, validate credit card formats dynamically, or orchestrate rich user interactions.

JavaScript provides:

  1. Dynamic DOM Manipulation: Creating, reading, updating, and removing HTML nodes in response to user events.
  2. Asynchronous Communication (AJAX/Fetch): Communicating with backend APIs and databases seamlessly in the background.
  3. State Management: Remembering user preferences, shopping cart contents, and authentication states.
  4. Interactive Logic: Running complex calculations, algorithms, game loops, and form validations directly on the client machine.

3. Simple Explanation

Return to our house analogy:

  • HTML built the physical brick walls and rooms.
  • CSS painted the walls and styled the furniture.
  • JavaScript is the Smart Home Automation & Electrical System:
    • When someone rings the doorbell (a user click event), the intercom chimes and the camera feeds video to your phone (an event listener executing a function).
    • If the temperature drops below 18°C (a conditional if/else statement), the smart thermostat ignites the furnace.
    • When you press a keypad, the door verifies your security passcode (validation logic).

Without JavaScript, the house is a static museum. With JavaScript, the house becomes an intelligent living space.


4. Technical Explanation: The V8 Engine & Script Loading

Every modern browser features a high-performance JavaScript engine (such as Google Chromium's V8, Apple WebKit's JavaScriptCore, or Mozilla's SpiderMonkey).

JavaScript Source Code


Parser ──► Abstract Syntax Tree (AST)


Ignition (Bytecode Interpreter) ──► Immediate Execution

       ▼ (Profiles "Hot" Functions)
TurboFan (Optimizing JIT Compiler) ──► Highly Optimized Machine Code

Script Placement: <script defer> vs <script async>

When a browser encounters a traditional <script src="app.js"></script> tag, HTML parsing immediately halts (blocks) while the script is downloaded and executed.

Parser Blocking:
HTML:   ████████████[PAUSE DOWNLOAD & EXECUTE]████████████►

async:
HTML:   ██████████████████████[EXECUTE]██████████████████►
Script:       [DOWNLOAD]──────►

defer (Standard Production Practice):
HTML:   █████████████████████████████████████████████████►
Script:       [DOWNLOAD]──────────────► [EXECUTE AFTER DOM READY]

IMPORTANT

Always use defer for application scripts: <script src="app.js" defer></script>. The browser downloads the script in parallel in the background without blocking the HTML parser, and executes it only after the DOM is fully constructed, guaranteeing DOM nodes exist before your code runs.


5. Variables & Memory: var vs let vs const

Modern JavaScript (ES6+) introduced let and const to replace the error-prone legacy var:

Featurevar (Legacy — Avoid)let (Modern Mutable)const (Modern Immutable Reference)
ScopeFunction ScopeBlock Scope ({ ... })Block Scope ({ ... })
Re-declarationAllowed (Dangerous bugs)Throws SyntaxErrorThrows SyntaxError
ReassignmentAllowedAllowed (count = count + 1)Forbidden (TypeError)
HoistingHoisted with undefinedHoisted in TDZHoisted in TDZ

Temporal Dead Zone (TDZ):

Variables declared with let and const exist in the Temporal Dead Zone from the start of the block until the execution reaches their declaration line. Accessing them prematurely throws a ReferenceError instead of returning undefined.

javascript
// Const for all fixed values and objects/arrays
const API_BASE_URL = 'https://api.example.com/v1';
const userProfile = { id: 101, name: 'Alex Morgan' };

// Mutating properties of a const object is permitted!
userProfile.name = 'Alex Rivera'; // Valid!

// Reassigning the const reference itself throws an error:
// userProfile = {}; // TypeError: Assignment to constant variable.

// Let for values that naturally change over time
let currentScore = 0;
currentScore += 10;

6. JavaScript Data Types & Type Coercion

JavaScript has 8 Data Types categorized into Primitives and Reference Types:

The 7 Primitive Types (Immutable, Stored by Value on the Stack):

  1. string: Textual data ('single', "double", or `template ${literal}`).
  2. number: 64-bit floating point numbers (42, 3.14159, NaN, Infinity).
  3. bigint: Arbitrary-precision integers (9007199254740991n).
  4. boolean: Logical values (true or false).
  5. undefined: A variable that has been declared but not assigned a value.
  6. null: Intentional representation of the absence of any object value.
  7. symbol: Unique, immutable identifier (Symbol('id')).

The Reference Type (Mutable, Stored by Reference on the Heap):

  1. object: Collections of key-value pairs (includes Plain Objects, Arrays, Functions, Dates, and RegExp).

Loose (==) vs Strict (===) Equality:

javascript
// Loose equality performs implicit type coercion (AVOID!):
console.log(5 == '5');   // true (String converted to Number)
console.log(0 == false); // true
console.log(null == undefined); // true

// Strict equality compares both VALUE and TYPE (Always use === in production):
console.log(5 === '5');  // false (Number !== String)
console.log(0 === false); // false

7. Operators, Strings & Math

Modern Operators:

  • Nullish Coalescing (??): Returns right-hand side ONLY if left is null or undefined (unlike || which triggers on 0 or ""):
    javascript
    const count = 0;
    const resultOr = count || 10;   // 10 (Bug! 0 treated as falsy)
    const resultNullish = count ?? 10; // 0 (Correct! 0 is a valid number)
  • Optional Chaining (?.): Safely accesses deeply nested properties without throwing a TypeError if a parent is nullish:
    javascript
    const user = { profile: null };
    console.log(user.profile?.address?.city); // undefined (No crash!)

Template Literals & String Methods:

javascript
const firstName = 'Alex';
const balance = 1420.5;

// Template Literal with embedded expression
const message = `Welcome back, ${firstName.toUpperCase()}! Your balance is $${balance.toFixed(2)}.`;

// Essential methods
console.log("  frontend development  ".trim()); // "frontend development"
console.log("system.json".endsWith(".json"));     // true
console.log("apple,banana,orange".split(","));    // ['apple', 'banana', 'orange']

Math & Number Parsing:

javascript
console.log(Math.round(4.7)); // 5
console.log(Math.floor(4.9)); // 4
console.log(Math.ceil(4.1));  // 5
console.log(Math.random());   // Float between 0 (inclusive) and 1 (exclusive)

// Generating random integer between min and max:
function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

8. Control Flow, Loops & Functions

Functions: Declarations vs Arrow Functions:

javascript
// 1. Function Declaration (Hoisted to top of scope)
function calculateTotal(price, taxRate = 0.18) {
  return price + (price * taxRate);
}

// 2. Arrow Function (Concise syntax, lexical 'this' binding)
const multiply = (a, b) => a * b;

// 3. Rest Parameters (...args gathers extra arguments into an Array)
const sumAll = (...numbers) => {
  return numbers.reduce((acc, curr) => acc + curr, 0);
};
console.log(sumAll(10, 20, 30, 40)); // 100

9. Arrays & Core Methods

Arrays are ordered lists of indexed items:

javascript
const fruits = ['Apple', 'Banana', 'Cherry'];

// Mutating methods (Modifies original array in place)
fruits.push('Date');    // Adds to end
fruits.pop();           // Removes from end
fruits.unshift('Avocado'); // Adds to start
fruits.shift();         // Removes from start

// Non-mutating methods (Returns a brand new copy)
const subset = fruits.slice(1, 3); // ['Banana', 'Cherry']
const hasBanana = fruits.includes('Banana'); // true

// Iteration
fruits.forEach((fruit, index) => {
  console.log(`${index}: ${fruit}`);
});

10. Objects & Reference Semantics

javascript
const developer = {
  id: 101,
  name: 'Alex Morgan',
  skills: ['HTML', 'CSS', 'JavaScript'],
  isEmployed: true,
  // Method shorthand
  getGreeting() {
    return `Hi, I am ${this.name}`;
  }
};

// Dot notation vs Bracket notation
console.log(developer.name);         // 'Alex Morgan'
const key = 'skills';
console.log(developer[key]);         // Access via dynamic variable

// Object Destructuring
const { name, skills } = developer;
console.log(name, skills);

11. The Document Object Model (DOM)

The DOM is the browser's in-memory object representation of the rendered HTML document. JavaScript manipulates the DOM via the global document interface.

Selecting Elements:

javascript
// 1. Single element (returns first match or null)
const mainTitle = document.querySelector('#main-heading');
const submitBtn = document.querySelector('.btn-primary');

// 2. Multiple elements (returns a static NodeList)
const navLinks = document.querySelectorAll('nav a');

// Iterating over a NodeList
navLinks.forEach(link => {
  link.style.color = '#0ea5e9';
});

Modifying Elements: Text, HTML & Classes:

javascript
const statusCard = document.querySelector('.status-card');

// 1. Text vs HTML
statusCard.textContent = 'Updated Status'; // Safe! Escapes HTML tags automatically.
// statusCard.innerHTML = '<strong>Alert</strong>'; // Parses HTML. DANGEROUS with user input (XSS risk)!

// 2. Manipulating CSS Classes (Industry Standard Pattern)
statusCard.classList.add('active');
statusCard.classList.remove('hidden');
statusCard.classList.toggle('highlight');
const hasActive = statusCard.classList.contains('active'); // true

// 3. Attributes
const userImage = document.querySelector('#avatar');
userImage.setAttribute('alt', 'User profile avatar');
console.log(userImage.getAttribute('src'));

12. Events & Form Handling

Browsers follow an Event-Driven Architecture. We attach event listeners to elements to execute callback functions when users interact with the page:

javascript
const form = document.querySelector('#contactForm');
const emailInput = document.querySelector('#userEmail');
const messageBox = document.querySelector('#formFeedback');

form.addEventListener('submit', (event) => {
  // CRITICAL: Prevent native browser full-page reload!
  event.preventDefault();

  const enteredEmail = emailInput.value.trim();

  if (!enteredEmail.includes('@')) {
    messageBox.textContent = 'Please enter a valid email address.';
    messageBox.style.color = '#ef4444';
    emailInput.focus();
    return;
  }

  // Success flow
  messageBox.textContent = `Thank you! Confirmation sent to ${enteredEmail}`;
  messageBox.style.color = '#10b981';
  form.reset();
});

13. Visual / Mental Model: Event-Driven Execution

[ User Action: Clicks Button ]


[ Browser OS Dispatches Event Object: MouseEvent ]


[ Event Target: <button class="btn"> ]


[ Invokes Registered Listener: btn.addEventListener('click', callback) ]


[ JavaScript Engine Executes Callback Function ]


[ Modifies DOM: Updates textContent / classList ]


[ Browser Repaints Updated DOM on Screen ]

14. Common Mistakes & Gotchas

  1. Forgetting event.preventDefault() on Forms:
    • If omitted on a submit listener, the browser attempts an HTTP POST request and instantly reloads the page, wiping out all JavaScript state.
  2. Confusing textContent with innerHTML:
    • Never inject untrusted user input using .innerHTML. If a malicious user submits <img src=x onerror=alert(1)>, your site becomes vulnerable to Stored Cross-Site Scripting (XSS). Use .textContent for text!
  3. Comparing Objects by Value:
    javascript
    console.log({ a: 1 } === { a: 1 }); // false! (Different memory references)
    console.log([] === []);             // false!
  4. Using for...in on Arrays:
    • for...in iterates over object keys (strings) including prototype properties. For arrays, always use for...of or .forEach().

15. Technical Interview Questions & Answers

Q1: What is the difference between var, let, and const, and what is the Temporal Dead Zone?

Answer: var is function-scoped (or globally scoped if declared outside a function), can be re-declared, and is hoisted with an initial value of undefined. In contrast, let and const are block-scoped (confined to the enclosing { ... }), cannot be re-declared in the same scope, and cannot be reassigned in the case of const. While let and const declarations are also hoisted, they are not initialized; the window of execution between the start of the block and the declaration statement is known as the Temporal Dead Zone (TDZ). Accessing the variable within the TDZ throws an immediate ReferenceError.

Q2: What is the difference between NodeList and HTMLCollection?

Answer: An HTMLCollection (returned by legacy methods like getElementsByClassName and getElementsByTagName) is a live collection of elements that automatically updates in real-time when matching DOM nodes are added or removed, but lacks modern array utility methods. A NodeList (returned by querySelectorAll) is typically a static snapshot of the DOM at the exact moment of invocation. Unlike HTMLCollection, a NodeList can contain comment nodes and text nodes, and provides a native .forEach() method for clean iteration.


16. Quick Revision Checkpoints

  • Always declare variables using const by default; use let only when values must be reassigned. Never use var.
  • Load production scripts using <script src="..." defer></script>.
  • Always use strict equality (===) to avoid dangerous type coercion bugs.
  • Use querySelector and querySelectorAll for clean, CSS-like element selection.
  • Use event.preventDefault() in form submission listeners to stop unwanted page reloads.
  • Prefer textContent over innerHTML to eliminate XSS vulnerabilities.

17. Next Topic & Learning Path

Proceed to Module 06 — Advanced JavaScript, Async & APIs, where we explore closures, execution contexts, this binding, functional array programming, Promises, async/await, the Event Loop, and the Fetch API!

G-TEC Jain Keerti Education — Global Leader in IT Education