Part 2: JavaScript
In Part 2, we explore JavaScript, the programming language of the web. Created by Brendan Eich in 1995 at
Netscape in just 10 days, JavaScript has grown from a simple browser scripting language into one of the most
popular and versatile languages in the world. Today, JavaScript runs not only in every web browser but also on
servers ([Link]), in mobile apps (React Native), in desktop applications (Electron), and even in embedded
systems and IoT devices. Understanding JavaScript is essential for any modern software developer.
2.1 Running JavaScript
The easiest way to run JavaScript is in your browser's developer console (press F12). For server-side JavaScript,
install [Link]. Node also includes npm (Node Package Manager), the largest ecosystem of open-source libraries
in the world. You can run a file with node [Link] or start an interactive REPL with node.
$ node --version
v20.10.0
$ npm --version
10.2.0
# Run a script
$ node [Link]
Hello, World!
# Start REPL
$ node
> 2 + 2
4
> .exit
# In browser console:
> [Link]('Hello, World!')
Hello, World!
2.2 Hello World
JavaScript code can be embedded in HTML using script tags, or run standalone with [Link]. The [Link]
function prints to the console. In browsers, it prints to the developer console. With [Link], it prints to the terminal.
// [Link]
[Link]('Hello, World!');
// In HTML:
// <script>
// [Link]('Hello from HTML!');
// </script>
// Or link an external file:
// <script src="[Link]"></script>
2.3 Variables and Data Types
Modern JavaScript uses let for mutable variables and const for constants. The older var is function-scoped and
Page 1
Part 2: JavaScript
should generally be avoided. JavaScript is dynamically typed with primitive types (number, string, boolean, null,
undefined, symbol, bigint) and the object type (which includes arrays, functions, and objects).
// Variable declarations
let age = 30; // mutable
const name = 'Alice'; // immutable binding
var old = true; // legacy, avoid
// Primitive types
let num = 42; // number (integers and floats are both 'number')
let float = 3.14; // also 'number'
let str = 'Hello'; // string
let bool = true; // boolean
let nothing = null; // null (intentional absence)
let undef; // undefined (uninitialized)
let big = 9007199254740991n; // bigint (for large integers)
let sym = Symbol('id'); // symbol (unique identifier)
// Type checking
[Link](typeof num); // 'number'
[Link](typeof str); // 'string'
[Link](typeof bool); // 'boolean'
[Link](typeof null); // 'object' (historic bug!)
[Link](typeof undef); // 'undefined'
// Template literals (backticks)
let greeting = `Hello, ${name}! You are ${age} years old.`;
[Link](greeting);
// Arrays (ordered, mutable)
let fruits = ['apple', 'banana', 'cherry'];
[Link]('date');
[Link](fruits[0]); // 'apple'
[Link]([Link]); // 4
// Objects (key-value pairs)
let person = {
name: 'Bob',
age: 25,
hobbies: ['reading', 'coding'],
greet() { return `Hi, I'm ${[Link]}`; }
};
[Link]([Link]); // 'Bob'
[Link]([Link]()); // "Hi, I'm Bob"
2.4 Control Flow
JavaScript supports standard control flow constructs including if-else, switch, for, while, do-while, and for-of/for-in
loops. Modern JavaScript (ES6+) added for-of for iterating over iterable objects like arrays and strings, and for-in
for object keys.
Page 2
Part 2: JavaScript
// If-else
let score = 85;
if (score >= 90) {
[Link]('A');
} else if (score >= 80) {
[Link]('B');
} else {
[Link]('F');
}
// Switch
let day = 3;
switch (day) {
case 1: [Link]('Monday'); break;
case 2: [Link]('Tuesday'); break;
case 3: [Link]('Wednesday'); break;
default: [Link]('Another day');
}
// For loop (traditional)
for (let i = 0; i < 5; i++) {
[Link](`Iteration ${i}`);
}
// For-of (iterable values - arrays, strings)
for (const fruit of fruits) {
[Link](fruit);
}
// For-in (object keys - use for objects only)
for (const key in person) {
[Link](`${key}: ${person[key]}`);
}
// While loop
let count = 0;
while (count < 3) {
[Link](`Count: ${count}`);
count++;
}
// Ternary operator
let status = age >= 18 ? 'adult' : 'minor';
[Link](status); // 'adult'
2.5 Functions
Functions are first-class citizens in JavaScript. They can be assigned to variables, passed as arguments, and
returned from other functions. Modern JavaScript has function declarations, function expressions, and arrow
functions. Arrow functions have a concise syntax and lexically bind the this keyword, making them ideal for
Page 3
Part 2: JavaScript
callbacks.
// Function declaration (hoisted)
function add(a, b) {
return a + b;
}
// Function expression (not hoisted)
const subtract = function(a, b) {
return a - b;
};
// Arrow function (ES6+, lexically binds this)
const multiply = (a, b) => a * b;
const square = x => x * x; // single param, no parens needed
const greet = () => 'Hello!'; // no params
const log = (x) => { // block body for multi-line
[Link](x);
return x;
};
// Default parameters
function greetUser(name = 'Guest') {
return `Hello, ${name}!`;
}
[Link](greetUser()); // 'Hello, Guest!'
[Link](greetUser('Bob')); // 'Hello, Bob!'
// Rest parameters (variadic)
function sumAll(...nums) {
return [Link]((a, b) => a + b, 0);
}
[Link](sumAll(1, 2, 3, 4, 5)); // 15
// Higher-order functions
function apply(func, value) {
return func(value);
}
[Link](apply(square, 5)); // 25
// Closures
function makeCounter() {
let count = 0;
return () => ++count;
}
const counter = makeCounter();
[Link](counter()); // 1
[Link](counter()); // 2
[Link](counter()); // 3
Page 4
Part 2: JavaScript
2.6 Arrays and Array Methods
JavaScript arrays come with a rich set of built-in methods for functional programming. The most important are map
(transform each element), filter (select elements), reduce (accumulate into a single value), forEach (iterate), find,
some, every, and sort. These methods enable declarative, immutable data transformations.
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// map - transform each element
const doubled = [Link](n => n * 2);
[Link](doubled); // [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
// filter - select elements matching a condition
const evens = [Link](n => n % 2 === 0);
[Link](evens); // [2, 4, 6, 8, 10]
// reduce - accumulate into a single value
const sum = [Link]((acc, n) => acc + n, 0);
[Link](sum); // 55
// Chaining methods (functional pipeline)
const result = numbers
.filter(n => n % 2 === 0) // [2, 4, 6, 8, 10]
.map(n => n * n) // [4, 16, 36, 64, 100]
.reduce((a, b) => a + b, 0); // 220
[Link](result);
// Other useful methods
const fruits2 = ['apple', 'banana', 'cherry', 'apple'];
[Link]([Link](f => f === 'banana')); // 'banana'
[Link]([Link]('cherry')); // true
[Link]([Link]('apple')); // 0
[Link]([Link](f => [Link] > 6)); // true
[Link]([Link](f => [Link] > 0)); // true
[Link]([...new Set(fruits2)]); // unique: ['apple','banana','cherry']
// Spread operator
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];
[Link](arr2); // [1, 2, 3, 4, 5]
// Destructuring
const [first, second, ...rest] = arr2;
[Link](first, second, rest); // 1 2 [3, 4, 5]
2.7 Objects and Classes
JavaScript uses prototype-based inheritance, but ES6 introduced class syntax that makes OOP more familiar.
Under the hood, classes are still based on prototypes. Classes support constructors, methods, inheritance with
extends, static methods, getters/setters, and private fields (with # prefix).
Page 5
Part 2: JavaScript
class Animal {
#name; // private field
constructor(name) {
this.#name = name;
}
get name() { return this.#name; }
speak() { return `${this.#name} makes a sound`; }
static create(name) { return new Animal(name); }
}
class Dog extends Animal {
constructor(name) {
super(name); // call parent constructor
}
speak() {
return `${[Link]()} - Woof!`; // call parent method
}
fetch() {
return `${[Link]} fetches the ball`;
}
}
const dog = new Dog('Rex');
[Link]([Link]()); // 'Rex makes a sound - Woof!'
[Link]([Link]()); // 'Rex fetches the ball'
[Link]([Link]('Cat').name); // 'Cat'
// Object shorthand and methods
const x = 10, y = 20;
const point = { x, y, toString() { return `(${x},${y})` } };
[Link]([Link]()); // '(10,20)'
2.8 Asynchronous JavaScript
JavaScript is single-threaded and uses an event loop for asynchronous operations. Promises represent a value
that may not be available yet. The async/await syntax makes asynchronous code look synchronous. This is crucial
for I/O operations like fetching data from a server, reading files, or querying a database without blocking the main
thread.
// Promises
function fetchUser(id) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (id > 0) {
resolve({ id, name: 'Alice' });
} else {
reject(new Error('Invalid id'));
}
}, 1000);
});
Page 6
Part 2: JavaScript
// Using .then() / .catch()
fetchUser(1)
.then(user => [Link](user))
.catch(err => [Link](err));
// async/await (cleaner syntax)
async function getUser(id) {
try {
const user = await fetchUser(id);
[Link](user);
return user;
} catch (err) {
[Link](err);
}
}
getUser(1);
// [Link] (run multiple in parallel)
async function getAll() {
const [user1, user2] = await [Link]([
fetchUser(1),
fetchUser(2),
]);
[Link](user1, user2);
}
// Fetch API (browser/Node 18+)
async function getData() {
const res = await fetch('[Link]
if (![Link]) throw new Error(`HTTP ${[Link]}`);
const data = await [Link]();
return data;
}
2.9 Modules
Modern JavaScript uses ES modules (ESM) with import and export statements. This replaced the older
CommonJS (require/[Link]) used by [Link]. ESM is supported in browsers (with type="module" in script
tags) and in [Link] (with .mjs extension or "type": "module" in [Link]).
// [Link] - exports
export function add(a, b) {
return a + b;
}
export const PI = 3.14159;
export default function multiply(a, b) { // default export
return a * b;
}
Page 7
Part 2: JavaScript
// [Link] - imports
import multiply, { add, PI } from './[Link]';
[Link](multiply(3, 4)); // 12
[Link](add(2, 3)); // 5
[Link](PI); // 3.14159
// Import everything as namespace
import * as math from './[Link]';
[Link]([Link](1, 1)); // 2
// Dynamic import (returns a Promise)
const module = await import('./[Link]');
[Link]([Link](5, 5)); // 10
2.10 The DOM and Events
In the browser, JavaScript can manipulate the DOM (Document Object Model) to dynamically update web pages.
The document object provides methods to find and create elements. Event listeners let you respond to user
interactions like clicks, key presses, and form submissions. This is what makes web pages interactive.
// Selecting elements
const button = [Link]('#myButton');
const items = [Link]('.item');
const para = [Link]('myPara');
// Creating elements
const div = [Link]('div');
[Link] = 'card';
[Link] = 'Hello, DOM!';
[Link](div);
// Event listeners
[Link]('click', (event) => {
[Link]('Button clicked!', [Link]);
[Link] = 'blue';
});
// Form submission
[Link]('form').addEventListener('submit', (e) => {
[Link](); // prevent page reload
const formData = new FormData([Link]);
[Link]([Link](formData));
});
// Event delegation (one listener for many elements)
[Link]('#list').addEventListener('click', (e) => {
if ([Link] === 'LI') {
[Link]('Clicked:', [Link]);
}
Page 8
Part 2: JavaScript
});
// Modern DOM update with template literals
const users = [{name: 'Alice'}, {name: 'Bob'}];
[Link]('#users').innerHTML =
[Link](u => `<li>${[Link]}</li>`).join('');
2.11 Summary of Part 2
We covered JavaScript from basics to modern features: variables and types, control flow, functions (including
arrow functions and closures), array methods for functional programming, classes and OOP, asynchronous
programming with Promises and async/await, ES modules, and DOM manipulation with events. JavaScript's
ubiquity across web, mobile, and server makes it one of the most valuable languages to learn. In Part 3, we
explore PHP, the language that powers much of the web's server-side.
Page 9