Skip to content

JavaScript

Introduction to JavaScript

Video content coming soon

JavaScript is the language of the web browser. While we will write our Angular applications using the TypeScript programming language, it will be compiled to JavaScript during our build process. Understanding JavaScript is fundamental to understanding how Angular works and how your code ultimately runs in the browser.

How Browsers Load and Interpret JavaScript

Section titled “How Browsers Load and Interpret JavaScript”

Understanding script loading helps you optimize performance.

Script Tag Placement:

<!-- Blocks HTML parsing (old way) -->
<script src="app.js"></script>
<!-- Defers execution until HTML parsed (modern) -->
<script src="app.js" defer></script>
<!-- Loads async, executes when ready -->
<script src="app.js" async></script>

Loading Process:

  1. Browser encounters <script> tag
  2. Downloads JavaScript file (if external)
  3. Parses JavaScript code
  4. Executes code
  5. Continues rendering HTML

Why This Matters: Angular is loaded as JavaScript in the browser. Understanding script loading explains why your app takes time to start and how to optimize load times.

Further Reading:

JavaScript differs from statically-typed languages.

Dynamic Typing:

let x = 42; // x is a number
x = "hello"; // now x is a string (allowed!)
x = true; // now x is a boolean (still allowed!)

Contrast with TypeScript:

let x: number = 42;
x = "hello"; // ERROR: Type 'string' not assignable to 'number'

Characteristics:

  • Types determined at runtime, not compile time
  • Variables can hold any type
  • Type errors only found by running code
  • Flexible but error-prone

Why This Matters: This explains why TypeScript exists and why Angular uses it. TypeScript adds type safety to catch errors before runtime. Understanding JavaScript’s dynamic nature helps you appreciate TypeScript’s benefits.

Further Reading:

How JavaScript became modern.

Timeline:

  • 1995: JavaScript created in 10 days by Brendan Eich at Netscape
  • 1997: ECMAScript standard established
  • 1999: ES3 - widely supported, stable period
  • 2009: ES5 - JSON support, strict mode
  • 2015: ES6/ES2015 - HUGE update: classes, modules, arrows, promises, let/const
  • 2016+: Annual releases (ES2016, ES2017, etc.) with incremental features

Key ES6+ Features (what Angular uses):

  • let/const instead of var
  • Arrow functions: () => {}
  • Classes: class MyClass {}
  • Modules: import/export
  • Template literals: `Hello ${name}`
  • Destructuring: const {prop} = obj
  • Promises and async/await

Why This Matters: Angular is built on modern JavaScript (ES6+). Code examples you find use these features. Understanding this evolution helps you read documentation and recognize modern patterns.

Further Reading:

Limitations of JavaScript (The “Sandbox”)

Section titled “Limitations of JavaScript (The “Sandbox”)”

Browsers restrict JavaScript for security.

What JavaScript CAN’T Do:

  • Access your file system directly (can’t read/write files outside browser)
  • Access other programs on your computer
  • Make network requests to any domain (CORS restrictions)
  • Access hardware directly (no raw USB/camera access without APIs)
  • Run system commands

What JavaScript CAN Do:

  • Manipulate the current web page (DOM)
  • Make HTTP requests (with restrictions)
  • Store data locally (LocalStorage, IndexedDB)
  • Use browser APIs (camera, geolocation with permission)

Why Restrictions Exist:

  • Security: Malicious websites can’t steal your files
  • Privacy: Sites can’t spy on you
  • Stability: Bad code can’t crash your computer

Why This Matters: Understanding these limits explains why Angular apps need backend servers for file storage, database access, etc. Angular runs in the sandbox - server provides capabilities beyond it.

Further Reading:

How JavaScript Communicates with the Server

Section titled “How JavaScript Communicates with the Server”

Modern ways to exchange data with servers.

Fetch API (Modern Standard):

// GET request
fetch('https://api.example.com/users')
.then(response => response.json())
.then(data => console.log(data));
// POST request
fetch('https://api.example.com/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'John' })
});
// With async/await (cleaner)
async function getUsers() {
const response = await fetch('https://api.example.com/users');
const data = await response.json();
return data;
}

XMLHttpRequest (Older):

  • Pre-dates Fetch
  • More complex API
  • Still works, but Fetch preferred

WebSockets (Real-time):

  • Persistent two-way connection
  • Server can push data anytime
  • Use for chat, live updates

Server-Sent Events (SSE):

  • One-way server-to-client
  • Simpler than WebSockets
  • Use for notifications, live feeds

In Angular:

  • Use HttpClient service (wraps Fetch/XHR)
  • Built-in support for observables
  • Handles many details for you

Why This Matters: Most Angular apps fetch data from APIs. Understanding these mechanisms helps you work with Angular’s HTTP services and debug network issues.

Further Reading:

Cross-Origin Resource Sharing prevents unauthorized data access.

The Problem:

  • JavaScript on http://myapp.com wants data from http://api.other.com
  • Browser blocks this by default (security)

Same-Origin Policy:

  • Scripts can only request data from their own origin
  • Origin = protocol + domain + port
  • http://example.com:80https://example.com:443

CORS Solution:

  • Server must explicitly allow cross-origin requests
  • Server sends Access-Control-Allow-Origin header
  • Browser checks header and allows/blocks request

Example:

// From http://myapp.com
fetch('http://api.other.com/data') // Blocked unless...
// Server responds with:
// Access-Control-Allow-Origin: http://myapp.com

Why This Matters: CORS errors are common when developing Angular apps that call APIs. Understanding CORS helps you:

  • Configure development servers properly
  • Work with backend developers to fix CORS issues
  • Understand why “it works in Postman but not in the browser”

Further Reading:

JavaScript can access browser capabilities through APIs.

Common Browser APIs:

  • DOM: Manipulate HTML (covered in next section)
  • Fetch: Network requests
  • LocalStorage: Store data in browser
  • Geolocation: Get user’s location
  • Web Storage: Session and local storage
  • Canvas: Draw graphics
  • Web Audio: Play and manipulate sound
  • Notifications: Show system notifications
  • Service Workers: Offline functionality, push notifications

Example:

// Geolocation API
navigator.geolocation.getCurrentPosition(position => {
console.log(position.coords.latitude, position.coords.longitude);
});
// LocalStorage API
localStorage.setItem('username', 'john');
const name = localStorage.getItem('username');

Why This Matters: Angular apps often use these APIs. Understanding what’s available helps you build rich features. Many APIs require user permission, affecting UX design.

Further Reading:

Features you’ll see in Angular code daily.

let and const (Block Scoping):

// Old way (var)
var x = 1;
if (true) {
var x = 2; // Same variable!
}
console.log(x); // 2
// New way (let/const)
let y = 1;
if (true) {
let y = 2; // Different variable
}
console.log(y); // 1
const z = 1;
z = 2; // ERROR: Cannot reassign const

Arrow Functions:

// Old way
function add(a, b) {
return a + b;
}
// New way
const add = (a, b) => a + b;
// With body
const greet = (name) => {
console.log(`Hello ${name}`);
};

Template Literals:

const name = 'John';
const age = 30;
// Old way
const msg = 'Hello ' + name + ', you are ' + age + ' years old';
// New way
const msg = `Hello ${name}, you are ${age} years old`;

Destructuring:

// Objects
const user = { name: 'John', age: 30 };
const { name, age } = user;
// Arrays
const [first, second] = [1, 2, 3];

Spread Operator:

const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // {a: 1, b: 2, c: 3}

Modules:

math.js
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;
// app.js
import { add, subtract } from './math.js';

Why This Matters: Angular code uses these features extensively. Understanding them is essential for reading and writing Angular components.

Further Reading:

Handling asynchronous operations.

The Problem:

// This doesn't work - data not ready yet!
const data = fetch('https://api.example.com/users');
console.log(data); // Promise, not actual data

Promises (ES6):

fetch('https://api.example.com/users')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));

Async/Await (ES2017 - Cleaner):

async function getUsers() {
try {
const response = await fetch('https://api.example.com/users');
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}

Promise States:

  • Pending: Operation in progress
  • Fulfilled: Operation completed successfully
  • Rejected: Operation failed

Why This Matters: Angular HTTP calls return Observables, but understanding Promises/async-await is crucial for asynchronous JavaScript. Many concepts carry over. You’ll use async/await in Angular services and components.

Further Reading:

Functional programming methods for transforming data.

map (Transform Each Item):

const numbers = [1, 2, 3, 4];
const doubled = numbers.map(n => n * 2); // [2, 4, 6, 8]
const users = [{name: 'John'}, {name: 'Jane'}];
const names = users.map(u => u.name); // ['John', 'Jane']

filter (Keep Items That Match):

const numbers = [1, 2, 3, 4, 5];
const evens = numbers.filter(n => n % 2 === 0); // [2, 4]

find (Get First Match):

const users = [{id: 1, name: 'John'}, {id: 2, name: 'Jane'}];
const user = users.find(u => u.id === 2); // {id: 2, name: 'Jane'}

reduce (Combine Into Single Value):

const numbers = [1, 2, 3, 4];
const sum = numbers.reduce((total, n) => total + n, 0); // 10

Other Useful Methods:

  • forEach: Loop through array
  • some: Check if any item matches
  • every: Check if all items match
  • findIndex: Get index of first match
  • includes: Check if value exists

Why This Matters: Angular code heavily uses these methods, especially with RxJS observables. They’re more concise and less error-prone than traditional loops. Mastering these makes you a more effective Angular developer.

Further Reading:

Type coercion vs strict equality.

Loose Equality (==):

5 == "5" // true (converts string to number)
0 == false // true
null == undefined // true

Strict Equality (===):

5 === "5" // false (different types)
0 === false // false
null === undefined // false

Rule: Always Use ===

  • More predictable
  • Avoids unexpected type conversions
  • ESLint and TypeScript encourage it

Why This Matters: Bugs from == are common and hard to track. Using === prevents these issues. Angular codebases use === exclusively.

Further Reading:

How JavaScript evaluates values in boolean contexts.

Falsy Values (evaluate to false):

false
0
"" (empty string)
null
undefined
NaN

Everything Else is Truthy:

true
42
"hello"
[] (empty array)
{} (empty object)

Common Use:

if (user) { // Check if user exists
console.log(user.name);
}
const name = user.name || 'Guest'; // Default value

Why This Matters: Truthy/falsy checks are everywhere in JavaScript and Angular. Understanding them prevents bugs and helps you write concise conditional logic.

Further Reading:

this refers to the execution context - but it’s tricky.

In Methods:

const person = {
name: 'John',
greet() {
console.log(`Hello, I'm ${this.name}`); // 'this' = person
}
};
person.greet(); // "Hello, I'm John"

Lost Context:

const greet = person.greet;
greet(); // "Hello, I'm undefined" - lost context!

Arrow Functions (Fix):

const person = {
name: 'John',
greet: () => {
console.log(`Hello, I'm ${this.name}`); // 'this' from outer scope
}
};

In Classes:

class Component {
name = 'MyComponent';
handleClick() {
console.log(this.name); // Works in Angular
}
}

Why This Matters: this context issues cause bugs in event handlers and callbacks. Angular handles most of this for you, but understanding it prevents confusion when this doesn’t refer to what you expect.

Further Reading:

Review & Practice

📝 Review Questions

Interactive review questions will be added here to help reinforce key concepts.

💻 Practice Exercises

Hands-on coding exercises will be available here to apply what you've learned.