0% found this document useful (0 votes)
1 views25 pages

JavaScript_Fundamentals_Revision_Guide

This Technical Revision Guide provides a comprehensive walkthrough of the learn-JavaScript repository, covering JavaScript fundamentals across five modules. It includes explanations, core code examples, and contextual insights for each topic, along with key takeaways and identified bugs. The guide is structured to aid learners in understanding JavaScript concepts and their applications in future frameworks like React and Node.js.

Uploaded by

raniaarsal1
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1 views25 pages

JavaScript_Fundamentals_Revision_Guide

This Technical Revision Guide provides a comprehensive walkthrough of the learn-JavaScript repository, covering JavaScript fundamentals across five modules. It includes explanations, core code examples, and contextual insights for each topic, along with key takeaways and identified bugs. The guide is structured to aid learners in understanding JavaScript concepts and their applications in future frameworks like React and Node.js.

Uploaded by

raniaarsal1
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd

TECHNICAL 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

About This Guide


This document walks through every script in the learn-JavaScript repository, folder by folder, in
the same order you wrote them. For each topic you get: a plain-language explanation, the core
code from the repo, and the kind of context an instructor would add in class — why the
behaviour happens, where it commonly trips people up, and how it connects to things you will
see later (React, [Link], FastAPI work, etc.).
Three boxes appear throughout:
• Key Takeaway — the one-sentence rule to remember.
• Bug Spotted in This Repo — a handful of real issues found while reading your code, called
out so you do not memorise them as correct.
• Good to Know — a related fact that was not in the repo but is worth having in your back
pocket.

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

6.1 for Loops, break & continue................................................................................................19


6.2 while & do-while.................................................................................................................19
6.3 for...of & the Map Object.....................................................................................................19
6.4 for...in & forEach.................................................................................................................20
6.5 filter() & map().....................................................................................................................20
6.6 reduce()................................................................................................................................21
7. All Bugs Spotted, In One Place.................................................................................................22
8. One-Page Cheat Sheet...............................................................................................................23
9. Logical Next Steps.....................................................................................................................25

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.

Folder What it covers


01_Basics Printing, variables, data types, type conversion, comparisons,
memory model, strings, numbers/Math, dates
02_Basics Arrays and array methods, objects, object methods, destructuring
03_Basics Functions, parameters, scope & closures, arrow functions, IIFEs
04_ControlFlow if/else, switch, truthy/falsy values, ternary, nullish coalescing
05_iterations for / while / do-while loops, for...of, for...in, forEach, filter, map,
reduce

pg. 5
● JavaScript Fundamentals — Revision Guide

2. Module 1 — The Basics


Folder: 01_Basics • 10 files • Variables, data types, conversion, comparisons, memory, strings,
numbers, dates

2.1 Printing to the Console


[Link]() is JavaScript’s primary debugging tool. It prints to the terminal when running
through [Link], or to the browser’s DevTools console when running in a browser — these are
two different JavaScript runtimes, and that distinction matters a lot once you reach functions like
alert() or document, which only exist in the browser.

[Link]("Hey, my name is rafay");

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.

2.2 Variables: var, let, const


JavaScript gives you three ways to declare a variable, and the repo deliberately compares all
three:

Keyword Behaviour

const Cannot be reassigned after declaration. Use this by default.

let Can be reassigned. Respects block scope — a let inside { } stays


inside { }.
var Can be reassigned. Ignores block scope — it leaks out of { } into
the enclosing function/global scope. This is why modern
JavaScript avoids var.

const accountId = 123 // can never be reassigned


let accountName = "Rafay" // can be reassigned
accountName = "Rafay khan"

var accountPass = "12344566" // works, but leaks out of block scope

BUG SPOTTED IN THIS REPO


Line 32 of 02_variables.js writes accountEmail = "rafay123@[Link]" with no const/let/var in front
of it. Because the file is not in strict mode, JavaScript silently creates an implicit global variable
instead of throwing an error. It still "works" here, but it is a classic source of bugs in larger programs
— always declare your variables explicitly.

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.

2.3 Data Types & "use strict"


JavaScript has 7 primitive types — number, bigint, string, boolean, null, undefined, and symbol
— plus the non-primitive object type (which arrays and functions are built on top of). typeof tells
you which one you are holding.

"use strict"

[Link](typeof "Rafay") // "string"


[Link](typeof 20) // "number"
[Link](typeof null) // "object" <-- a famous quirk

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.

2.4 Type Conversion & Coercion


Conversion is explicit (you call Number(), String(), or Boolean() yourself). Coercion is implicit
(JavaScript converts types for you, usually inside an operator like +).

Number(null) // 0
Number("33abc") // NaN (Not a Number)
Boolean(1) // true
Boolean("") // false

"1" + 2 // "12" -> string concatenation wins


1 + "2" // "12"
"1" + 2 + 2 // "122" (left to right: "1"+2="12", "12"+2="122")
1 + 2 + "2" // "32" (left to right: 1+2=3, 3+"2"="32")

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.

2.5 Comparisons: == vs ===

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.

"2" == 2 // true (string coerced to number)


"2" === 2 // false (different types, no coercion)

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.

2.6 Primitive vs Reference Types (Recap)


Primitives (number, string, boolean, null, undefined, symbol, bigint) are compared and copied by
value. Objects, arrays, and functions are reference types — a variable holding one of these
actually holds an address pointing to the data, not the data itself.

const heros = ["Superman", "Batman", "Flash"]


[Link](heros)

const id = Symbol("123")
const anotherId = Symbol("123")
[Link](id === anotherId) // false — every Symbol is unique, even with the same label

2.7 Stack vs Heap Memory


This is the mechanism behind the value-vs-reference split above. Primitives live on the stack:
each variable gets its own independent slot, so copying one never affects the other. Objects live
on the heap: the variable on the stack only stores a reference (a pointer) to the shared object, so
two variables pointing at the same object both see any change.

let myName = "rafay"


let firstName = myName
firstName = "Khan"
[Link](myName) // "rafay" — untouched

let userOne = { email: "userone123@[Link]" }


let userTwo = userOne // same object in heap memory
[Link] = "usertwo124@[Link]"

pg. 8
● JavaScript Fundamentals — Revision Guide

[Link]([Link]) // "usertwo124@[Link]" — changed too!

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)).

2.8 Strings & String Methods


Beyond quotes, template literals (backticks) let you embed expressions directly inside a string
with ${ }, which is far more readable than concatenation.

let name = "rafay", repoCount = 50


[Link](`My name is ${name} and i have repo count of ${repoCount}`)

const fullName = new String("raf-ay")


[Link] // 6
[Link]() // "RAF-AY"
[Link](2) // "f"
[Link]("y") // 4
[Link](0, 2) // "ra" (extracts by start/end index)
[Link](-6, 4) // negative index counts from the end
" rafay ".trim() // "rafay" — strips outer whitespace
"a-b-c-d-e".split("-", 3) // ["a","b","c"] — limit to first 3 pieces

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.

2.9 Numbers & Math


const balance = new Number(100)
[Link](2) // "100.00" — fixed decimal places, returns a string
(21231.893284).toPrecision(3) // "2.12e+4" — total significant digits
(10000000).toLocaleString("en-PK")

[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

2.10 Dates & Time


let myDate = new Date() // current date & time
let myCreatedDate = new Date("2023-01-14")
[Link]() // year
[Link]() // 0–11 (January is 0, not 1!)
[Link]() // day of month, 1–31
[Link]() // milliseconds since 1 Jan 1970 (the "Unix epoch")

BUG SPOTTED IN THIS REPO


getMonth() being zero-indexed (0 = January, 11 = December) is one of the most common sources of
off-by-one bugs in JavaScript date handling — it is not a mistake in the repo, but it is a trap worth
memorising now rather than debugging later.

pg. 10
● JavaScript Fundamentals — Revision Guide

3. Module 2 — Arrays & Objects


Folder: 02_Basics • 5 files • Array methods, object literals, merging, destructuring

3.1 Arrays: Indexing & Core Methods


Arrays in JavaScript are resizable, ordered lists, and under the hood they are actually a special
kind of object — which is why typeof [] returns "object", not "array".

const myArr = [0,1,2,3,4,5,6,7,8,9]


[Link](10) // add to the end
[Link]() // remove from the end
[Link](-1) // add to the start (shifts everything right)
[Link]() // remove from the start (shifts everything left)
[Link](5) // position of value 5
[Link](4) // true/false, is 4 present?
[Link]() // turns the array into a comma-separated string
[Link](1,5) // returns a NEW sub-array, original untouched
[Link](1,3,5,7,8) // MUTATES the original: remove 3 items from index 1, insert 5,7,8

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).

3.2 Merging, Flattening & Array Factories


const all_heroes = marvel_heroes.concat(dc_heroes)
const all_heroes2 = [...marvel_heroes, ...dc_heroes] // spread — same result, more flexible

const nested = [1,2,[3,4,[5,6]]]


[Link](Infinity) // [1,2,3,4,5,6] — flattens every level of nesting

[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".

3.3 Object Literals & Key Access

pg. 11
● JavaScript Fundamentals — Revision Guide

const mySym = Symbol("key_1")


const user = {
name: "Rafay",
"full name": "Rafay Khan", // needs bracket access, has a space
[mySym]: "key_1", // computed/symbol key
age: 20,
}

[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

BUG SPOTTED IN THIS REPO


In 03_objects.js, [Link](user) is written but commented out, while the very next line’s
comment claims "wont overwrite the email because we just used freeze." Since the freeze() call
never actually ran, the overwrite does succeed in practice. Keep this in mind when revising: the
comment describes the intended lesson, not what the commented-out code actually does.
[Link](obj), when actually called, makes an object’s top-level properties read-only in strict
mode (silently ignored writes in sloppy mode).
Functions can live inside objects too (often called "methods"). Inside a regular function method,
this refers back to the object it was called on:

[Link] = function () {
[Link](`hello user ${[Link]}`) // "this" = the user object
}

3.4 Merging & Inspecting Objects


const obj3 = [Link]({}, user1, user2) // merges into a NEW empty object
const user3 = { ...user1, ...user2 } // spread — same effect, more common today

[Link](tinderUser_1) // array of property names


[Link](tinderUser_1) // array of values
[Link](tinderUser_1) // array of [key, value] pairs
tinderUser_1.hasOwnProperty("id") // true/false

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:

[Link]?.[Link] // returns undefined instead of throwing if fullName is


missing

3.5 Destructuring Objects

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.

const course = { coursename: "Data", price: "123", courseInstructor: "Rafay" }


const { courseInstructor: inst } = course
[Link](inst) // "Rafay"

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

4. Module 3 — Functions & Scope


Folder: 03_Basics • 5 files • Functions, parameters, scope, closures, arrow functions, IIFE

4.1 Function Basics: Declaration, Parameters, Return


function addTwoNumbers(num1, num2) { // num1, num2 = "parameters"
let result = num1 + num2
return result // execution stops here — nothing after return runs
}
const result = addTwoNumbers(3, 9) // 3, 9 = "arguments" — the actual values passed

function loginUserMessage(userName = "rafay") { // default parameter


if (userName === undefined) {
return
}
return `${userName} just logged in.`
}

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.

4.2 Rest Parameters & Passing Objects/Arrays


function calculateCartPrice(val1, val2, ...num1) {
return num1 // every extra argument collected into a real array
}
calculateCartPrice(200, 300, 500, 900) // val1=200, val2=300, num1=[500, 900]

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

4.3 Scope & Closures


Scope decides where a variable is visible. const and let are block-scoped (confined to the nearest
{ }); var is function-scoped (it ignores blocks and leaks to the whole function). A closure is what
happens when an inner function "remembers" variables from the outer function it was defined in,
even after the outer function has finished running.

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.

4.4 Arrow Functions & "this"


Arrow functions (() => {}) are shorter to write, but their real difference from regular functions is
how they handle this. A regular function gets its own this, decided by how it is called. An arrow
function has no this of its own — it borrows this from whatever scope it was written inside (this
is called "lexical this").

const user = {
username: "Rafay",
welcome: function () {
[Link]([Link]) // "Rafay" — this = user, because welcome() was called as [Link]()
}
}

const myDrink = () => {


[Link]([Link]) // undefined — arrow functions don’t get their own "this"
}

const addTwo = (num1, num2) => num1 + num2 // implicit return, single expression
const makeUser = (num1, num2) => ({ username: "Rafay" }) // returning an OBJECT needs ( ) around it

BUG SPOTTED IN THIS REPO


It is easy to write (num1, num2) => { username: "Rafay" } by mistake. JavaScript reads the { } as a

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.

4.5 IIFE — Immediately Invoked Function Expression


An IIFE defines a function and calls it in the very same statement, so it runs exactly once and
never gets a name you could accidentally reuse or overwrite later — historically the main way
JavaScript avoided polluting the global scope before block-scoped let/const and ES Modules
existed.

(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

5. Module 4 — Control Flow


Folder: 04_ControlFlow • 3 files • if/else, switch, truthy/falsy, ternary, nullish coalescing

5.1 if / else & Comparison Operators


const temp = 60
if (temp < 50) {
[Link]("temperature is less than 50")
} else {
[Link]("temperature is greater than 50")
}

if (balance > 500) [Link]("test"); // no { } needed for a single statement

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

5.2 switch / case


A switch statement compares one value against several possible cases — a cleaner alternative to
a long chain of if / else if when you are checking the same variable repeatedly.

switch (month) {
case 1: [Link]("Jan"); break;
case 2: [Link]("Feb"); break;
// ...
default: [Link]("Default month matched"); break;
}

BUG SPOTTED IN THIS REPO


Forgetting break inside a case is one of the most common switch bugs: execution would "fall
through" into the next case below it and keep running until it hits a break or the end of the switch.
Every case in the repo’s example correctly ends in break, which is exactly the habit to keep.

5.3 Truthy / Falsy, Nullish Coalescing & Ternary


Any value can be used where a boolean is expected — JavaScript converts it. Only a short, fixed
list of values are "falsy"; everything else is "truthy".

pg. 17
● JavaScript Fundamentals — Revision Guide

Falsy (treated as false) Truthy (treated as true)

0, -0, 0n (BigInt zero) Any non-empty string, including "0" and "false"

"" (empty string) [] and {} — even when empty!

null, undefined, NaN Any function

const userEmail = "rkhan@[Link]"


if (userEmail) { [Link]("Got user email:") } // truthy check, no need for === true

// 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)

// Ternary operator: condition ? ifTrue : ifFalse


num <= 4 ? [Link]("less than 4") : [Link]("greater than 4")

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

6. Module 5 — Loops & Iteration


Folder: 05_iterations • 6 files • for, while/do-while, for...of, for...in, forEach, filter, map, reduce

6.1 for Loops, break & continue


for (let i = 1; i <= 20; i++) {
if (i == 5) {
continue // skip JUST this iteration, loop keeps going
}
[Link](i) // prints 1–4, then 6–20 — 5 is skipped
}

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.

6.2 while & do-while


while checks its condition before running the loop body — if the condition starts false, the body
never runs. do-while checks AFTER running the body once, so the body always executes at least
one time.

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)

BUG SPOTTED IN THIS REPO


The third example in 02_whileAnddo-[Link] loops while (arr <= [Link]) over a 4-item
array, logging the whole array each pass instead of indexing into it (myArr[arr]). Since valid indices
only run from 0 to length-1, the <= bound makes the loop run one extra time (5 passes instead of 4)
without ever actually reading individual elements — a classic off-by-one that is easy to miss because
nothing visibly "breaks". When you do want to read by index, the safe boundary is arr <
[Link].

6.3 for...of & the Map Object

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.

const map = new Map()


[Link]("PK", "Pakistan")
[Link]("UAE", "United Arab Emirates")

for (const [key, value] of map) {


[Link](key, "=>", value)
}

const myObj = { game_1: "GTA 6", game_2: "Call of Duty" }


for (const i of myObj) { } // TypeError: myObj is not iterable

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.

6.4 for...in & forEach


const myObj = { js: "javascript", cpp: "c++", Py: "python" }
for (const key in myObj) {
[Link](`${key} => ${myObj[key]}`) // for...in gives you KEYS
}

const coding = ["js", "ruby", "typescript", "cpp", "kotlin"]


[Link]((item, index, arr) => {
[Link](item, index) // forEach calls your callback once per element automatically
})

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.

6.5 filter() & map()


Both methods take a callback and return a brand-new array, leaving the original untouched.
filter() keeps only the elements where the callback returns true. map() transforms every element
into something new.

const books = [ { title: "Book Four", genre: "History", date: 2000 }, /* ... */ ]
const newBooks = [Link]((bk) => [Link] === "History" && [Link] >= 1900)

const nums = [1,2,3,4,5,6,7,8,9,10]


const newNums = nums
.map((num) => num * 10) // [10,20,...,100]
.map((num) => num + 1) // [11,21,...,101]
.filter((num) => num < 50) // [11,21,31,41] <- chaining multiple methods together

pg. 20
● JavaScript Fundamentals — Revision Guide

BUG SPOTTED IN THIS REPO


05_maps.js contains a real syntax issue worth knowing about, even though it is commented out
before it can run: const nums is declared TWICE with const in the same file/scope (once near the
top, once again further down). Running this as-is throws SyntaxError: Identifier ’nums’ has already
been declared. const and let can only be declared once per scope — if you need a second list, give it
a different name.

BUG SPOTTED IN THIS REPO


The commented-out filter() attempt earlier in the same file is a textbook example of the curly-brace
return trap: [Link]((num) => { num > 5 }) returns an empty array, because wrapping the
callback body in { } turns num > 5 into a statement whose result is thrown away — you must
explicitly write return num > 5. Without { }, (num) => num > 5 returns the comparison
automatically (an "implicit return").

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 myNums = [1,2,3,4]


const total = [Link]((acc, currVal) => acc + currVal, 0) // 0 = starting value of acc
// pass: acc=0,curr=1 -> 1 | acc=1,curr=2 -> 3 | acc=3,curr=3 -> 6 | acc=6,curr=4 -> 10

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

7. All Bugs Spotted, In One Place


Every "Bug Spotted" box from this guide, gathered here for quick revision before you re-read the
actual files.

File Issue

01_Basics/02_variables.js accountEmail is assigned with no const/let/var — creates an


unintended implicit global variable.
02_Basics/03_objects.js [Link](user) is commented out, but the next comment still
claims the email "wont overwrite" — it actually does, since freeze
never ran.
03_Basics/04_arrowFunctions.js Returning an object from an arrow function needs ({ }) — without
the outer parentheses, { } is read as a function body, not an object.
05_iterations/02_whileAnddo- while (arr <= [Link]) runs one extra, off-by-one iteration;
[Link] should be < length when indexing.
05_iterations/05_maps.js const nums is declared twice in the same scope — throws
SyntaxError if run as written.
05_iterations/05_maps.js The commented filter() example omits return inside { }, which
silently returns undefined for every element.

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

8. One-Page Cheat Sheet


Declaring variables
Snippet Note
const x = 1 Cannot reassign. Default choice.
let x = 1 Can reassign. Block-scoped.
var x = 1 Avoid — leaks out of blocks.

Type checks & conversion


Snippet Note
typeof x Returns the type as a string. typeof null is "object".
Number(x) / String(x) / Explicit conversion.
Boolean(x)
x === y Strict equality — no type conversion. Prefer this over ==.
x ?? fallback Use fallback only if x is null/undefined.

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

{ ...a, ...b } Shallow merge, b overwrites a on collisions.


[Link]/values/entries(obj) Get keys, values, or [key,value] pairs as arrays.
const { key: alias } = obj Destructure and rename in one step.
obj?.nested?.value Optional chaining — safe access, no throw if missing.

Functions & scope


Snippet Note
function f(a, b = 1) {} Default parameter, used only when the argument is undefined.
function f(a, ...rest) {} Rest parameter — collects extra arguments into an array.
const f = (a, b) => a + b Arrow function, implicit return.
const f = () => ({ a: 1 }) Arrow function returning an object — needs ( ).
(function () { })() IIFE — runs once immediately.

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

9. Logical Next Steps


This repo covers core JavaScript syntax thoroughly. The natural next milestones — especially
given the [Link], React, and FastAPI work already on your plate — are:

Topic Why it matters next

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

You might also like