🌍 freeCodeCamp · subject
freeCodeCamp JavaScript Algorithms and Data Structures Syllabus
The JavaScript Algorithms and Data Structures syllabus for freeCodeCamp in full: 7 chapters and 24 topics, every one listed below, plus 50 JavaScript Algorithms and Data Structures flashcards with answers.
JavaScript Algorithms and Data Structures syllabus: all 7 chapters
Expand any chapter to see its topics and sub-topics.
-
JavaScript Fundamentals
4 topics- Variables and Data Types
- Operators and Expressions
- Conditionals
- Loops
-
Functions
3 topics- Function Declarations and Expressions
- Arrow Functions
- Scope and Closures
-
Arrays and Objects
3 topics- Array Methods
- Object Manipulation
- Iteration and Lookups
-
Object Oriented Programming
3 topics- Constructors and Prototypes
- Classes
- this Keyword
-
Functional Programming
3 topics- Pure Functions and Immutability
- Higher Order Functions
- Currying and Composition
-
Algorithmic Thinking
4 topics- Algorithm Design
- Searching and Sorting
- Recursion
- Regular Expressions
-
Certification Projects
4 topics- Palindrome Checker
- Roman Numeral Converter
- Telephone Number Validator
- Cash Register
freeCodeCamp JavaScript Algorithms and Data Structures flashcards — 50 questions with answers
What are the seven primitive data types in JavaScript?
string, number, bigint, boolean, undefined, symbol, and null. Everything else (objects, arrays, functions) is of type object (functions report "function" via typeof but are objects).
What is the difference between var, let, and const in JavaScript?
var is function-scoped, hoisted and initialized to undefined, and can be redeclared. let and const are block-scoped and in the temporal dead zone until declared. const additionally cannot be reassigned (though object contents it references can still be mutated).
What is the difference between undefined and null in JavaScript?
undefined means a variable has been declared but not assigned a value (the default). null is an intentional assignment representing "no value." Note: typeof undefined is "undefined" while typeof null is "object" (a historical quirk).
What is the difference between == and === in JavaScript?
== is loose equality: it performs type coercion before comparing (e.g., '5' == 5 is true). === is strict equality: it compares both value and type with no coercion ('5' === 5 is false). Best practice is to use ===.
List the eight falsy values in JavaScript.
false, 0, -0, 0n (BigInt zero), "" (empty string), null, undefined, and NaN. Every other value is truthy, including "0", [], and {}.
What do the logical operators && and || return in JavaScript (short-circuit evaluation)?
They return one of their operands, not necessarily a boolean. a && b returns a if a is falsy, otherwise b. a || b returns a if a is truthy, otherwise b. Evaluation stops as soon as the result is determined (short-circuiting).
What is the syntax and meaning of the ternary (conditional) operator?
condition ? valueIfTrue : valueIfFalse. It is an expression that evaluates the condition and returns the first value if truthy, otherwise the second. Example: const status = age >= 18 ? 'adult' : 'minor'.
Why must you usually include a break statement in each case of a switch statement?
Without break, execution "falls through" into the next case's code even though its value did not match. break exits the switch after the matched case runs. Intentional fall-through is used to let multiple case labels share one code block.
What are the three parts of a classic for loop header, and when does each run?
for (initialization; condition; final-expression): initialization runs once before the loop starts; the condition is checked before every iteration (loop runs while it is truthy); the final-expression (e.g., i++) runs after each iteration.
What is the difference between a while loop and a do...while loop?
A while loop checks its condition before each iteration, so the body may run zero times. A do...while loop runs the body first and checks the condition after, so the body always executes at least once.
What is the difference between for...of and for...in loops?
for...of iterates over the values of an iterable (arrays, strings, Maps, Sets). for...in iterates over the enumerable property keys of an object (including inherited ones). Use for...of for arrays and for...in for object keys.
What is the difference between a function declaration and a function expression?
A declaration (function foo() {}) is a standalone statement and is fully hoisted, so it can be called before it appears in the code. A function expression (const foo = function() {}) assigns a function to a variable; only the variable binding is hoisted, so calling it before the assignment throws an error.
What value does a JavaScript function return if it has no return statement?
undefined. A function with no return, or a bare return with no value, implicitly returns undefined.
What are default parameters and rest parameters in JavaScript functions?
Default parameters give an argument a fallback value when it is undefined: function greet(name = 'Guest'). The rest parameter collects all remaining arguments into a real array: function sum(...nums), allowing a variable number of arguments.
Write the arrow-function equivalent of: function double(x) { return 2 * x; }
const double = x => 2 * x; With a single parameter the parentheses are optional, and a single-expression body has an implicit return (no braces or return keyword needed).
How do arrow functions handle the this keyword differently from regular functions?
Arrow functions have no this of their own; they lexically inherit this from the enclosing scope at definition time. Regular functions get this dynamically from how they are called. Arrow functions therefore cannot be rebound with call/apply/bind and are unsuitable as object methods or constructors.
When must you use parentheses around the body of an arrow function that implicitly returns an object literal?
Always: const makeUser = name => ({ name }); Without the parentheses the braces are parsed as a function block, not an object, so the function would return undefined.
What is lexical scope in JavaScript?
Scope determined by where functions and blocks are written in the source code, not where they are called. Inner functions can access variables of all enclosing (outer) scopes; the engine resolves a variable by searching outward through the scope chain.
What is a closure in JavaScript?
A closure is a function bundled together with references to its lexical (outer) scope, allowing it to access outer variables even after the outer function has returned. Closures enable data privacy, counters, and function factories.
Given: function makeCounter() { let count = 0; return () => ++count; } const c = makeCounter(); — what does calling c() three times print, and why?
1, 2, 3. The returned arrow function closes over the count variable, so the same private count persists and increments across calls; each makeCounter() call would create an independent counter.
Show the other 30 JavaScript Algorithms and Data Structures flashcards
Compare the array methods map, filter, and reduce.
map transforms each element and returns a new array of the same length. filter returns a new array containing only elements for which the callback returns truthy. reduce folds all elements into a single accumulated value: arr.reduce((acc, cur) => ..., initialValue). None of them mutate the original array.
Which common array methods mutate the original array, and which return a new array?
Mutating: push, pop, shift, unshift, splice, sort, reverse, fill. Non-mutating (return new arrays/values): map, filter, slice, concat, reduce, plus ES2023 toSorted, toReversed, toSpliced.
What is the difference between Array.prototype.slice and Array.prototype.splice?
slice(start, end) returns a shallow copy of a portion of the array (end exclusive) without mutating it. splice(start, deleteCount, ...items) mutates the array by removing and/or inserting elements in place and returns the removed elements.
What is the difference between find, indexOf, and includes on arrays?
find(callback) returns the first element satisfying the callback (or undefined). indexOf(value) returns the index of the first strict-equality match (or -1). includes(value) returns a boolean and, unlike indexOf, can find NaN.
What do Object.keys, Object.values, and Object.entries return?
For an object, Object.keys returns an array of its own enumerable property names, Object.values an array of the corresponding values, and Object.entries an array of [key, value] pairs — useful for iterating objects with for...of or converting to a Map.
What is destructuring assignment? Give an object and an array example.
Syntax that unpacks values from arrays or properties from objects into variables. Object: const { name, age = 18 } = person; (with default). Array: const [first, second, ...rest] = list; It also supports renaming: const { name: userName } = person.
What does the spread operator (...) do with arrays and objects?
It expands an iterable or object's own enumerable properties in place: [...arr1, ...arr2] concatenates/copies arrays, {...obj, x: 1} makes a shallow copy with overrides, and fn(...args) spreads an array into individual arguments. Copies are shallow — nested objects are still shared references.
How do you check whether a property exists on an object in JavaScript (three ways)?
1) 'key' in obj — true for own and inherited properties. 2) obj.hasOwnProperty('key') (or Object.hasOwn(obj, 'key')) — own properties only. 3) obj.key !== undefined — simplest but fails if the property's value is literally undefined.
What are the average time complexities of lookup by key in an object/Map versus searching for a value in an array?
Object or Map lookup by key is $O(1)$ on average (hash-based). Searching an unsorted array for a value (indexOf, includes, find) is $O(n)$ linear scan. This is why lookup tables (objects/Maps/Sets) are used to optimize repeated membership checks.
When should you use a Map or Set instead of a plain object or array?
Map: when keys can be any type (not just strings/symbols), insertion order matters, or you need size directly. Set: to store unique values with $O(1)$ average add/has/delete — e.g., dedupe an array via [...new Set(arr)]. Plain objects suit simple string-keyed records; arrays suit ordered lists.
What is a constructor function in JavaScript, and what does the new operator do?
A constructor is a regular function (conventionally capitalized, e.g., function Dog(name) { this.name = name; }) meant to be called with new. new: (1) creates an empty object, (2) sets its prototype to Constructor.prototype, (3) runs the constructor with this bound to the new object, (4) returns the object (unless the constructor explicitly returns another object).
What is the prototype chain and how does property lookup use it?
Every object has an internal link to a prototype object. When a property is accessed and not found on the object itself, JavaScript searches its prototype, then the prototype's prototype, and so on until found or the chain ends at null. This is how inheritance and shared methods work.
Why are methods usually defined on Constructor.prototype instead of inside the constructor body?
A method assigned inside the constructor (this.bark = function(){}) is duplicated on every instance, wasting memory. Defining it once on Constructor.prototype means all instances share a single function via the prototype chain.
In an ES6 class, what are the roles of the constructor method and the super keyword?
constructor is the special method run when the class is instantiated with new; it initializes instance properties. In a subclass (class B extends A), super(args) calls the parent constructor and must run before using this; super.method() invokes a parent method.
What are getters and setters in a JavaScript class?
Accessor properties defined with get and set keywords. A getter runs when the property is read (const t = obj.temp) and a setter when it is assigned (obj.temp = 30), letting you compute values, validate input, or expose private fields while using plain property syntax.
What is the difference between static members and instance members in a JavaScript class?
Instance members (methods/fields) live on each object or its prototype and are accessed via the instance. static members belong to the class itself and are called on the class, e.g., Math-style utilities: ClassName.helper(). Static methods cannot access instance data through this.
What are the four rules that determine the value of this in a regular function?
1) new binding: this is the newly created object. 2) Explicit binding: call/apply/bind set this to the given object. 3) Implicit binding: called as obj.method(), this is obj. 4) Default: standalone call — this is the global object (or undefined in strict mode). Precedence is in that order; arrow functions ignore all four and use lexical this.
What is the difference between call, apply, and bind?
All three set a function's this explicitly. fn.call(thisArg, a, b) invokes immediately with arguments listed individually. fn.apply(thisArg, [a, b]) invokes immediately with arguments as an array. fn.bind(thisArg, a) does not invoke; it returns a new function with this (and optionally leading arguments) permanently fixed.
Why does a callback like setTimeout(obj.method, 1000) lose its this, and how do you fix it?
Passing obj.method detaches the function from obj, so when the timer calls it, this falls back to the global object/undefined. Fixes: setTimeout(obj.method.bind(obj), 1000) or wrap it: setTimeout(() => obj.method(), 1000).
What two conditions make a function "pure"?
1) Deterministic: it always returns the same output for the same inputs. 2) No side effects: it does not mutate external state, its arguments, or perform I/O. Pure functions are easier to test, memoize, and reason about.
What is immutability in functional JavaScript, and how do you update an array or object without mutating it?
Immutability means never changing existing data; instead you create modified copies. Arrays: use map/filter/slice/concat or spread ([...arr, item]) instead of push/splice. Objects: {...obj, key: newValue} instead of assignment. Object.freeze(obj) makes an object's own properties shallowly read-only.
Why is Array.prototype.sort a problem for immutability, and what are the fixes?
sort mutates (reorders) the original array in place. Fixes: sort a copy — [...arr].sort(compareFn) or arr.slice().sort(compareFn) — or use the non-mutating ES2023 method arr.toSorted(compareFn).
What is a higher-order function? Give two examples built into JavaScript.
A function that takes one or more functions as arguments and/or returns a function. Built-in examples: Array.prototype.map and Array.prototype.filter (take callbacks); Function.prototype.bind (returns a new function). User-defined examples include debounce and memoize.
What is a callback function?
A function passed as an argument to another function, to be invoked by that function at the appropriate time — e.g., the comparator in arr.sort((a, b) => a - b), event handlers, or the callback in setTimeout. Callbacks are the foundation of higher-order functions and async patterns.
What is currying? Show the curried form of add(a, b, c).
Currying transforms a function of multiple arguments into a chain of functions each taking one argument: const add = a => b => c => a + b + c; called as add(1)(2)(3) → 6. It enables partial application, e.g., const add5 = add(5).
What is function composition, and how do compose and pipe differ?
Composition combines functions so the output of one feeds the next: $(f \circ g)(x) = f(g(x))$. compose applies right-to-left: compose(f, g)(x) = f(g(x)); pipe applies left-to-right: pipe(f, g)(x) = g(f(x)). Implementation: const pipe = (...fns) => x => fns.reduce((v, fn) => fn(v), x).
What is Big O notation, and what do $O(1)$, $O(\log n)$, $O(n)$, $O(n \log n)$, and $O(n^{2})$ describe? Rank them from fastest to slowest growth.
Big O describes an algorithm's worst-case growth rate as input size $n$ grows, ignoring constants and lower-order terms. Fastest to slowest: $O(1)$ constant (array index/hash lookup) $<$ $O(\log n)$ logarithmic (binary search) $<$ $O(n)$ linear (single scan) $<$ $O(n \log n)$ (efficient sorts) $<$ $O(n^{2})$ quadratic (nested loops, bubble sort).
Describe the divide-and-conquer strategy and the recursion base case. What happens without a base case?
Divide and conquer splits a problem into smaller subproblems, solves them (often recursively), and combines the results — e.g., merge sort, binary search. Every recursive function needs a base case, a condition that returns without recursing (e.g., factorial: if (n <= 1) return 1). Without one, recursion never terminates and throws a stack overflow (RangeError: Maximum call stack size exceeded).
How does binary search work, what does it require, and what is its time complexity?
It requires a sorted array. Repeatedly compare the target to the middle element $m = \left\lfloor \frac{low + high}{2} \right\rfloor$: if equal, done; if the target is smaller, search the left half; if larger, the right half — halving the search space each step. Time complexity is $O(\log n)$, versus $O(n)$ for linear search on unsorted data.
Compare bubble sort, merge sort, and quicksort by time complexity and stability.
Bubble sort: repeatedly swaps adjacent out-of-order pairs; $O(n^{2})$ average and worst, stable, simple but slow. Merge sort: divide and conquer with merging; $O(n \log n)$ in all cases, stable, but needs $O(n)$ extra space. Quicksort: partition around a pivot; $O(n \log n)$ average but $O(n^{2})$ worst case (bad pivots), in-place and typically fastest in practice, not stable.
freeCodeCamp JavaScript Algorithms and Data Structures FAQ
What is in the freeCodeCamp JavaScript Algorithms and Data Structures syllabus?
freeCodeCamp JavaScript Algorithms and Data Structures is split into 7 chapters: JavaScript Fundamentals, Functions, Arrays and Objects, Object Oriented Programming, Functional Programming, Algorithmic Thinking and Certification Projects. Together they contain 24 topics.
How many chapters are in freeCodeCamp JavaScript Algorithms and Data Structures?
7 chapters, containing 24 topics. The largest chapter is JavaScript Fundamentals, with 4 topics.
Are there flashcards for freeCodeCamp JavaScript Algorithms and Data Structures?
Yes — a 50-card JavaScript Algorithms and Data Structures deck, printed in full in the flashcards section of this page and available in the Examius app with spaced repetition. The free plan covers one exam of your choice, including its flashcards; Examius Pro, a one-time purchase, unlocks every other exam and deck.