Skip to the content.

Prepared Based on: MAD 2 Introductory JavaScript Open Session

Target Audience: Beginners with Python background

Prepared by: Shri Krishna 

Last term live session for reference: Mad-2 week-2 open session Last term live session based on this doc: Mad-2 week-2 open session


1. Introduction

JavaScript is a versatile language that runs in multiple environments. To get started with JavaScript development, here are the main methods:

A. Running JavaScript in the Browser

All modern browsers come with built-in JavaScript engines. You can:

  1. Use the Browser Console

    • Open DevTools (F12 or right-click → Inspect → Console tab).
    • Type JavaScript directly and run it.
  2. Include JavaScript in HTML

    <script>
      alert("Hello from HTML script tag!");
    </script>
    

    Or link an external file:

    <script src="script.js"></script>
    

B. Running JavaScript with Node.js

Node.js allows you to run JavaScript outside the browser.

  1. Install Node.js

  2. Run a script

    node filename.js
    
  3. Use REPL (Read-Eval-Print Loop)

    node
    > console.log("Hello from Node.js");
    

C. Using Online Editors

  1. JSFiddle / CodePen / Replit

    • No installation needed.
    • Code and share directly in the browser.

D. Using Integrated Development Environments (IDEs)

the difference between a JavaScript engine and a JavaScript runtime, using Chrome and VS Code as examples:


1. JavaScript Engine

A JavaScript engine is the core program that parses and executes JavaScript code. It knows only how to understand and execute JavaScript, nothing more.

Example: Chrome uses V8

Think of V8 as the "brain" that knows JavaScript — but not how to interact with the browser or OS.


2. JavaScript Runtime

A JavaScript runtime is a full environment that uses a JavaScript engine (like V8) and provides additional tools/APIs that JS alone can't offer — like:

Example: Chrome’s JavaScript runtime

Example: VS Code running Node.js

Think of the runtime as a kitchen: the engine is the chef, the runtime includes the fridge, oven, ingredients, and tools.


🔍 Side-by-Side: Chrome vs. VS Code (with Node)

Feature Chrome (Browser Runtime) VS Code + Node.js (Server Runtime)
JS Engine V8 V8
Has DOM ✅ Yes ❌ No
Has setTimeout() ✅ Yes ✅ Yes (provided by Node)
Has fs module ❌ No ✅ Yes (Node's file system module)
Has document.querySelector() ✅ Yes ❌ No
Common use case Web apps, frontend Server-side scripting, backend

Summary

Concept JavaScript Engine JavaScript Runtime
What it is Core JS interpreter Full environment to run JS
Knows about JS syntax & semantics JS + APIs (DOM, timers, file system, etc.)
Example V8 Chrome runtime (browser), Node.js runtime

[ JavaScript Runtime ] ├── JS Engine (V8) ← The core interpreter (like car engine) ├── Timers (setTimeout, setInterval) ├── Console (console.log) ├── APIs (DOM in browser / fs in Node) └── Event Loop (handles async stuff)


2. JavaScript Basics

2.1 Syntax Overview

JavaScript syntax is similar to C-style languages. Statements end with semicolons (optional but recommended), and blocks are enclosed in curly braces.

let name = "Alice";
const age = 25;
console.log(name + " is " + age + " years old.");

This code declares two variables and prints a message using string concatenation.

2.2 Variable Declarations

JavaScript provides var, let, and const for declaring variables:

var x = 10;      // function scoped, hoisted
let y = 20;      // block scoped
const z = 30;    // block scoped, immutable

3. Data Types

JavaScript has two main categories: primitives and objects.

3.1 Primitive Types

let str = "Hello";   // string
let num = 42;        // number
let bool = true;     // boolean
let empty = null;    // null (intentional empty)
let undef;           // undefined (not assigned)

3.2 Objects

Objects are key-value pairs like Python dictionaries.

let person = {
  name: "Alice",
  age: 25
};
console.log(person.name);  // Accessing properties using dot notation

You can dynamically add or delete properties:

person.gender = "female";
delete person.age;

4. Control Flow

4.1 If-Else Statement

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

This is used for conditional branching.

4.2 Loops

For Loop

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

While Loop

let count = 0;
while (count < 3) {
  console.log(count);
  count++;
}

for...in and for...of Loops

JavaScript provides two distinct looping constructs for iterating over data structures: for...in and for...of. Understanding their differences is crucial for effective coding.

for...in Loop

Purpose: Iterates over the enumerable property keys of an object, including inherited properties.

Syntax:

for (let key in object) {
  // code block to be executed
}

Example:

const person = { name: "Alice", age: 30 };

for (let key in person) {
  console.log(key);         // Outputs: name, age
  console.log(person[key]); // Outputs: Alice, 30
}

Behavior:

Use Case: Best suited for iterating over object properties.

for...of Loop

Purpose: Iterates over the values of iterable objects like arrays, strings, maps, sets, etc.

Syntax:

for (let value of iterable) {
  // code block to be executed
}

Example:

const fruits = ["apple", "banana", "cherry"];

for (let fruit of fruits) {
  console.log(fruit); // Outputs: apple, banana, cherry
}

Behavior:

Use Case: Ideal for iterating over arrays, strings, maps, sets, and other iterable collections.

12.3 Comparison Table

Feature for...in for...of
Iterates Over Enumerable property keys Iterable values
Return Value Strings (keys) Actual values
Applicable To Objects (also arrays, but not ideal) Arrays, strings, maps, sets, etc.
Includes Inherited Properties Yes No
Iteration Order Not guaranteed Follows the order of the iterable
Use Case Accessing object properties Accessing values in iterable collections

Note: When iterating over arrays, it's recommended to use for...of or traditional for loops instead of for...in to avoid unexpected behaviors, especially if the array has custom properties or methods.

5. Arrays and Objects

5.1 Arrays

let fruits = ["apple", "banana", "cherry"];
fruits.push("date");  // Adds to end
console.log(fruits[0]);  // "apple"

5.2 Objects

let car = {
  make: "Toyota",
  model: "Corolla"
};
car.year = 2020;       // Dynamic property addition
delete car.model;      // Property deletion
console.log(car);

6. Execution Environments

JavaScript operates in various environments, primarily the browser and Node.js. Each environment provides a global object that serves as the top-level context for code execution.

6.1 Global Object in Different Environments

6.2 Use Cases and Examples

6.2.1 Using window in the Browser

The window object allows interaction with the browser window and its components.

Example: Accessing Global Variables and Functions

// Declaring a global variable
var siteName = "ExampleSite";

// Accessing the global variable via window
console.log(window.siteName); // Output: "ExampleSite"

// Defining a global function
function greetUser() {
  alert("Welcome to " + siteName);
}

// Invoking the global function via window
window.greetUser(); // Displays alert: "Welcome to ExampleSite"

Example: Using Browser-Specific Methods

// Displaying an alert dialog
window.alert("This is an alert box!");

// Opening a new browser window
window.open("https://www.example.com", "_blank");

6.2.2 Using global in Node.js

In Node.js, the global object provides access to globally available variables and functions.

Example: Defining and Accessing Global Variables

// Defining a global variable
global.appVersion = "1.0.0";

// Accessing the global variable
console.log(global.appVersion); // Output: "1.0.0"

Example: Using Global Functions

// Using setTimeout, a global function in Node.js
setTimeout(() => {
  console.log("Executed after 2 seconds");
}, 2000);

6.2.3 Using globalThis for Cross-Environment Compatibility

The globalThis object provides a standard way to access the global object, regardless of the environment.

Example: Defining a Global Variable

// Defining a global variable using globalThis
globalThis.config = {
  appName: "UniversalApp",
  version: "2.0.0"
};

// Accessing the global variable
console.log(globalThis.config.appName); // Output: "UniversalApp"

By using globalThis, developers can write code that is compatible across different JavaScript environments without worrying about the specific global object name.


7. Debugging Techniques

7.1 Console Methods

console.log("Info");
console.warn("Warning");
console.error("Error");

The browser console helps test and debug code.


8. Functions

8.1 Function Declaration

function greet() {
  console.log("Hello");
}

8.2 Function Expression

const greet = function() {
  console.log("Hello");
};
greet();

Not hoisted—must be declared before use.

8.3 Arrow Function

const greet = () => {
  console.log("Hello");
};
greet();

9. The this Keyword

Regular Function:

const user = {
  name: "Alice",
  greet: function() {
    console.log("Hi " + this.name);
  }
};
user.greet(); // Output: Hi Alice

Arrow Function:

const user = {
  name: "Alice",
  greet: () => {
    console.log("Hi " + this.name);
  }
};
user.greet(); // Output: Hi undefined (in browsers, likely "Hi " or "Hi undefined")

✅ Use arrow functions when:

❌ Avoid arrow functions when:


Summary Table

Feature Regular Function Arrow Function
Syntax function greet() {} const greet = () => {}
Hoisting ✅ Yes ❌ No
Own this ✅ Yes ❌ No (lexical this)
Use as constructor ✅ Yes ❌ No
Suitable for object method ✅ Yes ❌ No (usually not preferred)
Suitable for callbacks ✅ Sometimes ✅ Often preferred

10. Hoisting and Temporal Dead Zone (TDZ)

What is Hoisting? Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase. This means that:

Examples:

var example:

This demonstrates hoisting of variables declared with var. The declaration is hoisted, but the assignment is not, so a is undefined when logged:

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

let/const example:

Variables declared with let and const are hoisted but not initialized. Trying to access them before declaration results in a ReferenceError due to the Temporal Dead Zone (TDZ):

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

function declaration:

Function declarations are fully hoisted, so you can call them before the declaration appears in the code:

greet(); // "Hello"
function greet() {
  console.log("Hello");
}

function expression (not hoisted):

Function expressions assigned to variables (even with var) are not hoisted with their assigned function. Only the variable is hoisted and initialized to undefined, so calling it before the assignment results in a TypeError:

console.log(greet); // undefined
// console.log(greet()); // TypeError: greet is not a function
var greet = function() {
  return "Hello";
};
console.log(greet()); // "Hello"

With let or const, the variable is hoisted but not initialized. Trying to access it before declaration results in a ReferenceError due to the Temporal Dead Zone (TDZ):

// console.log(greetLet); // ReferenceError
const greetLet = function() {
  return "Hi there";
};
console.log(greetLet()); // "Hi there"

So while function declarations are fully hoisted, function expressions are only hoisted with their variable declaration — not the function assignment. This is important to understand for debugging and code structure.

Function expressions assigned to variables (even with var) are not hoisted with their assigned function. Only the variable is hoisted and initialized to undefined, so calling it before the assignment results in a TypeError:

greet(); // TypeError: greet is not a function
var greet = function() {
  console.log("Hello");
};
console.log(a); // undefined
var a = 5;

11. Scope in JavaScript

Definitions

11.1 Global Scope

Variables declared outside functions are accessible everywhere.

var globalVar = "I'm global";
let globalLet = "I'm a global let";
const globalConst = "I'm a global const";

function printGlobal() {
  console.log(globalVar);
  console.log(globalLet);
  console.log(globalConst);
}
printGlobal();

11.2 Function Scope

Variables declared with var inside a function are only available inside that function. let and const behave similarly but are scoped more strictly to blocks.

function example() {
  var localVar = "I'm a function-scoped var";
  let localLet = "I'm a function-scoped let";
  const localConst = "I'm a function-scoped const";
  console.log(localVar);
  console.log(localLet);
  console.log(localConst);
}
example();
// console.log(localVar); // ReferenceError
// console.log(localLet); // ReferenceError
// console.log(localConst); // ReferenceError

11.3 Block Scope

let and const are block-scoped, meaning they only exist within {}. var does not respect block scope.

if (true) {
  var a = 1;       // Accessible outside the block
  let b = 2;       // Block-scoped
  const c = 3;     // Block-scoped
  console.log(a, b, c); // 1 2 3
}

console.log(a);    // 1
// console.log(b); // ReferenceError
// console.log(c); // ReferenceError

11.4 Lexical Scope

Functions remember the scope in which they were defined.

function outer() {
  let name = "Alice";
  function inner() {
    console.log(name); // Alice
  }
  inner();
}
outer();

12. Best Practices

const MAX_USERS = 100;
let userCount = 0;

function addUser() {
  if (userCount < MAX_USERS) {
    userCount++;
  }
}

13. Summary

This session covered JavaScript syntax, data types, control flows, arrays, objects, function types, the this keyword, hoisting, execution environments, scoping, and best practices.

Practice Recommendations: