JavaScript_Fundamentals_Revision_Guide
JavaScript_Fundamentals_Revision_Guide
JavaScript Fundamentals
A Complete, File-by-File Walkthrough of the Repository
REPOSITORY [Link]/rafayykhan/learn-JavaScript
PREPARED FOR Muhammad Abdul Rafay Khan – Dev Weekends (Angry Bytes)
DATE June 2026
CONTENTS 5 modules • 29 topics • 6 flagged bugs • 1-page cheat sheet
pg. 1
● JavaScript Fundamentals — Revision Guide
pg. 2
● JavaScript Fundamentals — Revision Guide
Table of Contents
About This Guide............................................................................................................................2
Table of Contents.............................................................................................................................3
1. Repository Map...........................................................................................................................5
2. Module 1 — The Basics..............................................................................................................6
2.1 Printing to the Console...........................................................................................................6
2.2 Variables: var, let, const.........................................................................................................6
2.3 Data Types & "use strict".......................................................................................................6
2.4 Type Conversion & Coercion................................................................................................7
2.5 Comparisons: == vs ===........................................................................................................7
2.6 Primitive vs Reference Types (Recap)...................................................................................8
2.7 Stack vs Heap Memory..........................................................................................................8
2.8 Strings & String Methods......................................................................................................8
2.9 Numbers & Math...................................................................................................................9
2.10 Dates & Time.......................................................................................................................9
3. Module 2 — Arrays & Objects..................................................................................................11
3.1 Arrays: Indexing & Core Methods.......................................................................................11
3.2 Merging, Flattening & Array Factories................................................................................11
3.3 Object Literals & Key Access..............................................................................................11
3.4 Merging & Inspecting Objects.............................................................................................12
3.5 Destructuring Objects..........................................................................................................12
4. Module 3 — Functions & Scope...............................................................................................14
4.1 Function Basics: Declaration, Parameters, Return...............................................................14
4.2 Rest Parameters & Passing Objects/Arrays.........................................................................14
4.3 Scope & Closures.................................................................................................................14
4.4 Arrow Functions & "this"....................................................................................................15
4.5 IIFE — Immediately Invoked Function Expression............................................................16
5. Module 4 — Control Flow........................................................................................................17
5.1 if / else & Comparison Operators........................................................................................17
5.2 switch / case.........................................................................................................................17
5.3 Truthy / Falsy, Nullish Coalescing & Ternary.....................................................................17
6. Module 5 — Loops & Iteration.................................................................................................19
pg. 3
● JavaScript Fundamentals — Revision Guide
pg. 4
● JavaScript Fundamentals — Revision Guide
1. Repository Map
The repo is organised as five progressive modules. Numbers below count the concepts covered,
not just files.
pg. 5
● JavaScript Fundamentals — Revision Guide
GOOD TO KNOW
console also has [Link]() (prints arrays/objects as a grid), [Link](), [Link](), and
[Link]()/[Link]() for quick performance checks — all used later in this same repo.
Keyword Behaviour
KEY TAKEAWAY
pg. 6
● JavaScript Fundamentals — Revision Guide
Rule of thumb for 2026-era JavaScript: reach for const first. Switch to let only when you know the
value must change. Treat var as legacy syntax you should recognise but not write.
"use strict"
GOOD TO KNOW
"use strict" tells the engine to treat the file as modern JS: it throws real errors for things sloppy mode
silently allows, like assigning to an undeclared variable (the accountEmail case above) or assigning
to a read-only property. Placing it at the very top of a file or function is the only valid position.
KEY TAKEAWAY
typeof null returning "object" is a 25-year-old bug baked into the language for backward
compatibility — it can never be fixed without breaking the web. If you need to truly check for null,
compare directly: value === null.
Number(null) // 0
Number("33abc") // NaN (Not a Number)
Boolean(1) // true
Boolean("") // false
KEY TAKEAWAY
The + operator is the only arithmetic operator that also concatenates strings. If either side of + is a
string, JavaScript converts the other side to a string too. Every other operator (-, *, /) forces both
sides to numbers, so "5" - 2 gives 3, not an error.
pg. 7
● JavaScript Fundamentals — Revision Guide
== ("loose equality") converts both sides to a common type before comparing. === ("strict
equality") never converts — the types must already match.
null == 0 // false
null < 0 // false
null <= 0 // true
null >= 0 // true
GOOD TO KNOW
The null comparisons look contradictory but follow one rule: relational operators (<, >, <=, >=)
convert null to 0 before comparing, while == treats null as its own special case that only equals
undefined (and itself) — never 0. This is exactly why null >= 0 is true but null > 0 and null == 0 are
both false.
KEY TAKEAWAY
Default to === and !== in all new code. Reserve == only for the rare, deliberate case of checking "is
this null or undefined" with value == null.
const id = Symbol("123")
const anotherId = Symbol("123")
[Link](id === anotherId) // false — every Symbol is unique, even with the same label
pg. 8
● JavaScript Fundamentals — Revision Guide
KEY TAKEAWAY
To actually copy an object instead of sharing it, use a spread: const userTwo = { ...userOne }. That
creates a new object in the heap with the same values — a shallow copy. Nested objects inside it
would still be shared; that needs a deep copy (e.g. structuredClone(obj)).
GOOD TO KNOW
new String("raf-ay") creates a String object, not a primitive string — typeof would report "object"
here. In day-to-day code you almost always want the primitive (let s = "raf-ay"), which gets all the
same methods through the String prototype automatically. The object wrapper exists mainly so the
repo can demonstrate it.
KEY TAKEAWAY
substring() always treats negative or swapped arguments forgivingly (it reorders them), while slice()
supports true negative indexing ("count from the end"). When in doubt for everyday slicing, slice()
is the more predictable, more widely used choice.
[Link]([Link]() * (max - min + 1)) + min // random integer between min and max, inclusive
KEY TAKEAWAY
That random-integer formula is one of the most reused snippets in JavaScript. [Link]() alone
gives a decimal between 0 (inclusive) and 1 (exclusive); multiplying and flooring turns it into a
whole number in a chosen range.
pg. 9
● JavaScript Fundamentals — Revision Guide
pg. 10
● JavaScript Fundamentals — Revision Guide
KEY TAKEAWAY
slice() vs splice() trips up almost everyone at first. slice() is read-only and returns a copy. splice()
mutates the array it is called on and returns the removed items. If you need the original array
preserved, always reach for slice() (or the spread operator).
[Link]("Rafay") // false
[Link]("Rafay") // ["R","a","f","a","y"] — turns iterables into real arrays
[Link]({ name: "Rafay" }) // [] — plain objects have no numeric "length", so it gives up
[Link](100, 455, 728) // [100, 455, 728]
GOOD TO KNOW
[Link]() exists to fix a quirk of the Array constructor: new Array(5) creates an array with 5 empty
slots, while new Array(1,2,3) creates [1,2,3]. That inconsistency (one number = length, multiple
numbers = contents) is confusing, so [Link](5) was added to always mean "an array containing the
value 5".
pg. 11
● JavaScript Fundamentals — Revision Guide
[Link] // dot notation — clean, but cannot use spaces/variables as the key
user["full name"] // bracket notation — required for keys with spaces
user[mySym] // required to read a Symbol key at all
[Link] = function () {
[Link](`hello user ${[Link]}`) // "this" = the user object
}
KEY TAKEAWAY
[Link]({}, a, b) and { ...a, ...b } both produce a shallow merge where later sources overwrite
earlier ones on key collisions. The spread version reads slightly cleaner and is the modern default;
[Link]() is still useful when the target needs to be something other than a brand-new object.
Optional chaining (?.) is the safe way to read deeply nested properties without first checking
every level exists:
pg. 12
● JavaScript Fundamentals — Revision Guide
Destructuring pulls values out of an object into their own variables in one line — and you can
rename them on the way out, which is exactly what 05_objects.js demonstrates.
GOOD TO KNOW
This pattern is everywhere once you start working with APIs: data from a backend usually arrives as
JSON — either a single object ({ name, price, ... }) or an array of objects ([{}, {}, {}]) — and
destructuring is the standard way to pull exactly the fields a component or function needs.
pg. 13
● JavaScript Fundamentals — Revision Guide
KEY TAKEAWAY
A default parameter (userName = "rafay") only kicks in when the argument is undefined — passing
null or an empty string will NOT trigger the default. That is also why the if (userName ===
undefined) check inside the function above can never actually be true: the default already replaced
undefined before the function body even runs.
GOOD TO KNOW
Just writing myName (without parentheses) refers to the function itself — useful for passing it
around. myName() actually calls it. Mixing these up (forgetting the parentheses, or adding them
when you meant to pass a reference) is one of the most common beginner mistakes in JavaScript.
function handleObject(anyObject) {
[Link](`username is ${[Link]} and the price is ${[Link]}`)
}
handleObject({ username: "sam", price: 898 }) // objects can be passed inline
KEY TAKEAWAY
The rest operator (...num1) must always be the last parameter — JavaScript needs to know where the
"named" parameters end and the "collect everything else" parameter begins. It is the cleaner, modern
replacement for the old arguments object.
pg. 14
● JavaScript Fundamentals — Revision Guide
let a = 400
if (true) {
let a = 10 // a DIFFERENT "a", only visible inside this block
var c = 70 // leaks out of the block once the surrounding function/script runs
}
function one() {
const name = "rafay"
function two() {
[Link](name) // "two" can still see "name" — this is a closure
}
two()
}
GOOD TO KNOW
Function declarations (function one(){}) are hoisted — JavaScript loads the whole function into
memory before running any code, so you can call one() above where it is written in the file. Function
expressions assigned to a const/let (const addTwo = function(){}) are NOT hoisted the same way —
calling them before the line they are defined on throws an error, because of the temporal dead zone
that const/let variables live in until their declaration line runs.
const user = {
username: "Rafay",
welcome: function () {
[Link]([Link]) // "Rafay" — this = user, because welcome() was called as [Link]()
}
}
const addTwo = (num1, num2) => num1 + num2 // implicit return, single expression
const makeUser = (num1, num2) => ({ username: "Rafay" }) // returning an OBJECT needs ( ) around it
pg. 15
● JavaScript Fundamentals — Revision Guide
function body, not an object, so username: "Rafay" is parsed as a (useless) labelled statement and the
function silently returns undefined. Wrapping the object in parentheses — ({ username: "Rafay" })
— is the fix, and it is exactly what the repo does correctly.
KEY TAKEAWAY
Rule of thumb: use regular functions for object methods that need this to refer to the object, and
arrow functions for short callbacks (inside map, filter, forEach, setTimeout, etc.) where you want
this to stay whatever it already was outside.
(function chai() {
[Link]("DATABASE CONNECTED")
})(); // the leading ( ) wraps the function so JS treats it as an expression, not a declaration
(() => {
[Link]("Hi there")
})();
((name) => {
[Link](name)
})("rafay") // a named IIFE that also takes an argument
GOOD TO KNOW
You will still recognise this pattern in older bundled libraries and in module-loading code, even
though direct IIFE usage has become less common since ES Modules (import/export) became the
standard way to scope code per-file.
pg. 16
● JavaScript Fundamentals — Revision Guide
Operator Meaning
< > <= >= Standard relational comparisons
== != Loose equality — converts types before comparing
=== !== Strict equality — compares type AND value, no conversion
&& AND — every condition must be true
|| OR — at least one condition must be true
switch (month) {
case 1: [Link]("Jan"); break;
case 2: [Link]("Feb"); break;
// ...
default: [Link]("Default month matched"); break;
}
pg. 17
● JavaScript Fundamentals — Revision Guide
0, -0, 0n (BigInt zero) Any non-empty string, including "0" and "false"
// Nullish coalescing (??) — falls back ONLY for null or undefined, not for 0 or ""
let val1 = null ?? 10 // 10
let val2 = undefined ?? 15 // 15
let val3 = 0 ?? 99 // 0 (0 is not null/undefined, so the fallback never triggers)
KEY TAKEAWAY
?? is intentionally narrower than ||. value || fallback replaces ANY falsy value (including 0, "", and
false), which causes bugs when 0 or "" are legitimate values you wanted to keep. value ?? fallback
only replaces null or undefined, which is almost always what you actually mean when setting a
default.
pg. 18
● JavaScript Fundamentals — Revision Guide
GOOD TO KNOW
continue skips to the next loop iteration; break exits the loop entirely. Both also work inside while
and do-while loops, not just for loops.
let index = 0
while (index <= 10) {
if (index == 10) { break }
[Link](`Value of index is ${index}`)
index += 2
}
let score = 1
do {
[Link](`Score ${score}`)
score++
} while (score <= 10)
pg. 19
● JavaScript Fundamentals — Revision Guide
for...of iterates over the values of anything iterable — arrays, strings, Maps, Sets — but notably
NOT plain objects, which are not iterable by default.
KEY TAKEAWAY
Map vs plain object: a Map preserves insertion order reliably, allows any value (even an object) as a
key, and is directly iterable. A plain object is simpler for quick lookups by string keys but was never
designed to be looped over directly — that is what for...in (next section) or [Link]() exist for.
GOOD TO KNOW
for...in works on arrays too, but it gives you the index as a string ("0", "1", ...) rather than the value,
and it is technically meant for objects — using forEach (or for...of) on arrays is the conventional,
safer choice.
const books = [ { title: "Book Four", genre: "History", date: 2000 }, /* ... */ ]
const newBooks = [Link]((bk) => [Link] === "History" && [Link] >= 1900)
pg. 20
● JavaScript Fundamentals — Revision Guide
6.6 reduce()
reduce() collapses an entire array down to a single value by repeatedly running a callback that
carries an "accumulator" forward from one element to the next.
const shoppingCart = [ { item: "js course", price: 399 }, { item: "c++ course", price: 1099 } /* ... */ ]
const myTotal = [Link]((acc, item) => acc + [Link], 0)
KEY TAKEAWAY
reduce() is the most general of the array methods — you could technically rebuild map() and filter()
using only reduce(). The trade-off is readability: reach for map()/filter() when they fit, and save
reduce() for the cases that genuinely need to combine everything into one running result (sums,
totals, building a single object from a list, etc.).
pg. 21
● JavaScript Fundamentals — Revision Guide
File Issue
GOOD TO KNOW
None of these break the lessons themselves — the explanatory comments around each one are
accurate. They are flagged here purely so you do not accidentally memorise the literal code as bug-
free when revising later.
pg. 22
● JavaScript Fundamentals — Revision Guide
Arrays
Snippet Note
[Link](v) / [Link]() Add/remove from the end.
[Link](v) / [Link]() Add/remove from the start.
[Link](a,b) Copy, does not mutate.
[Link](i,n,...items) Mutates in place.
[...a, ...b] Spread — merge/copy arrays or objects.
[Link](Infinity) Flatten nested arrays fully.
[Link](fn) Transform every element → new array.
[Link](fn) Keep elements where fn returns true → new array.
[Link](fn, start) Collapse array into one value.
[Link](fn) Run fn for every element, no return value.
Objects
Snippet Note
[Link] / obj["key"] Dot vs bracket access. Bracket needed for dynamic/spaced keys.
pg. 23
● JavaScript Fundamentals — Revision Guide
Loops
Snippet Note
for (let i=0; i<[Link]; i++) Classic indexed loop.
for (const v of iterable) Values — arrays, strings, Maps, Sets.
for (const k in obj) Keys — objects (and array indices, as strings).
while (cond) {} Checks condition first.
do {} while (cond) Runs body at least once.
pg. 24
● JavaScript Fundamentals — Revision Guide
Classes & OOP (class, extends, JavaScript’s syntax for the object-oriented patterns you already
constructor) use in Python/Django.
Promises & async/await Required for anything that waits on a server, database, or timer —
the backbone of API calls.
fetch() / API calls How the browser (or Node) actually talks to a backend like your
FastAPI or Express services.
try / catch / finally Structured error handling, instead of letting errors crash the whole
program.
[Link]() / [Link]() Converting between JS objects and the JSON text format APIs
send/receive.
ES Modules (import / export) How real projects split code across files — the modern
replacement for the IIFE pattern.
DOM manipulation & events Only needed in the browser, not Node — selecting elements and
responding to clicks/input.
KEY TAKEAWAY
Given your existing Bloggio and PathFinder projects already use async backend calls, async/await
and fetch() will feel the most immediately useful — they are the logical next folder to add to this
same repo (e.g. 06_AsyncJS).
pg. 25