JavaScript Basics

Learn JavaScript fundamentals: variables, types, functions, arrays, objects, and control flow — the engine behind interactive web pages.

Medium 60m 3 tasks
Prerequisites: CSS Basics & Selectors

Learning Objectives

  • Declare variables with let, const, and understand scope
  • Use JavaScript data types and type coercion
  • Write functions including arrow functions
  • Manipulate arrays and objects
  • Understand asynchronous JavaScript: callbacks and Promises

Including JavaScript

<!-- End of body (preferred) -->
<script src="app.js"></script>

<!-- Defer — load parallel, execute after DOM -->
<script src="app.js" defer></script>

<!-- Module (enables import/export) -->
<script type="module" src="app.js"></script>

Variables

// const — cannot be reassigned (prefer this)
const host = "192.168.1.1";

// let — block-scoped, can be reassigned
let port = 80;
port = 443;

// var — avoid (function-scoped, hoisted, error-prone)
var old = "don't use";

Data Types

const str    = "Hello";           // string
const num    = 42;                 // number (int and float)
const float  = 3.14;
const bool   = true;
const arr    = [22, 80, 443];      // array
const obj    = { host: "10.0.0.1", port: 22 }; // object
const nil    = null;               // intentional absence
let  undef;                        // undefined

console.log(typeof str);  // "string"
console.log(typeof nil);  // "object" (JS quirk!)

Type Coercion — A Security Risk

// Loose equality (==) coerces types — AVOID
0 == "0"      // true
0 == false    // true
null == undefined // true

// Strict equality (===) — ALWAYS USE
0 === "0"     // false
0 === false   // false

// This can cause bugs in auth checks:
// if (userId == 0) → matches userId = "0" = false = null

Always use === and !==.

Strings

const ip = "192.168.1.1";
ip.split(".")          // ["192","168","1","1"]
ip.includes("192")     // true
ip.startsWith("192")   // true
ip.replace("1.1","1.2")// "192.168.1.2"
ip.toUpperCase()       // "192.168.1.1" (unchanged)
`Scanning ${ip}:80`    // template literal
ip.length              // 11

Arrays

const ports = [22, 80, 443, 8080];

ports.push(3306);         // add to end
ports.pop();              // remove from end
ports.includes(22);       // true
ports.indexOf(80);        // 1

// Higher-order array methods
const highPorts = ports.filter(p => p > 1024);   // [8080]
const labels    = ports.map(p => `port_${p}`);    // ["port_22",...]
const sum       = ports.reduce((acc, p) => acc + p, 0);

// Destructuring
const [first, second, ...rest] = ports;

Objects

const scan = {
  host:  "192.168.1.1",
  ports: [22, 80],
  up:    true,
};

// Access
scan.host          // dot notation
scan["host"]       // bracket notation
scan.os = "Linux"; // add property
delete scan.up;    // remove

// Destructuring
const { host, ports } = scan;

// Spread
const copy    = { ...scan, os: "Windows" };
const merged  = { ...defaults, ...overrides };

// Object methods
Object.keys(scan)    // ["host","ports"]
Object.values(scan)  // ["192.168.1.1",[22,80]]
Object.entries(scan) // [["host","192.168.1.1"],...]

Functions

// Function declaration
function greet(name) {
  return `Hello, ${name}!`;
}

// Function expression
const greet = function(name) { return `Hello, ${name}!`; };

// Arrow function (preferred for short functions)
const greet = (name) => `Hello, ${name}!`;
const square = n => n * n;
const add    = (a, b) => a + b;

// Default parameters
function scan(host, timeout = 1000) { ... }

// Rest parameters
function sumAll(...nums) {
  return nums.reduce((a, b) => a + b, 0);
}

Promises & Async/Await

JavaScript is single-threaded — async operations use Promises:

// Callback style (old)
setTimeout(() => console.log("done"), 1000);

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

// Async/await (preferred — reads like sync code)
async function getScanData(host) {
  try {
    const res  = await fetch(`/api/scan/${host}`);
    const data = await res.json();
    return data;
  } catch (err) {
    console.error("Scan failed:", err);
  }
}

getScanData("192.168.1.1").then(console.log);

Error Handling

try {
  const data = JSON.parse(userInput);
} catch (err) {
  console.error("Invalid JSON:", err.message);
} finally {
  cleanup();
}

// Custom errors
class ValidationError extends Error {
  constructor(msg) { super(msg); this.name = "ValidationError"; }
}
throw new ValidationError("Invalid IP address");

Security Notes

  • Never use eval() — executes arbitrary code
  • Never use innerHTML with user input — XSS vector
  • Use textContent instead of innerHTML for user data
  • === over == to prevent type confusion bugs

Open your browser console (F12 → Console). Declare variables using const and let. Test type coercion: check 0 == false vs 0 === false. Check typeof null.

✦ Answer the questions to complete this task

What does typeof null return in JavaScript?

Which equality operator checks type AND value?

Create an array of 10 port numbers. Use filter() to get ports > 1024, map() to label them as 'HIGH:port', and reduce() to sum all port numbers.

✦ Answer the questions to complete this task

What array method creates a new array with items that pass a test?

What array method transforms every item and returns a new array?

Write an async function getIP() that fetches https://httpbin.org/ip and returns the origin IP. Call it and log the result. Handle errors with try/catch.

✦ Answer the questions to complete this task

What keyword pauses async function execution until a Promise resolves?

What does res.json() return?

💪 Exercises & Challenges

📝 MCQ Medium +20 XP

JavaScript Basics MCQ

JavaScript Basics MCQ

Start →
⚙️ Practical Medium +30 XP

IP Validator

IP Validator

Start →
🚩 Challenge Hard +50 XP

Type Confusion Flag

Type Confusion Flag

Start →