Checkpoint: Modern JavaScript

Reviewed & published by Brayan K

A checkpoint is a hands-on review that combines everything from the modern JavaScript track — template literals, optional chaining, array and object methods, symbols, getters/setters, Proxy, and BigInt — into one build challenge and a short quiz.

Part of the free JavaScript course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

No new syntax here: this is where the pieces click together into something you could ship.

What You'll Practice in This Checkpoint

📋 What You've Learned

Here's the whole modern-JavaScript toolkit in one place. Each row links the idea to a one-line reminder.

ConceptOne-line reminder
Template literals`hi ${name}` — interpolation, multiline, tags
Optional chaining / ??a?.b ?? def — safe reads + null-only defaults
Array methodsfind, some, flatMap, toSorted
Object methodsentries, fromEntries, freeze, groupBy
SymbolsSymbol() — unique keys & Symbol.iterator
Getters / settersget/set + descriptor flags
Proxy & Reflectintercept ops with traps; forward via Reflect
BigInt10n — exact integers past the safe limit

🛠️ Build Challenge — A Mini Order Processor

Build a small utility that (1) reads each order's nested customer city safely with optional chaining, (2) groups orders by status using Object.groupBy, (3) finds the highest-value order with an array method, and (4) wraps a config object in a validating Proxy that rejects negative discounts. Fill in the blanks in the starter, then check against the full solution.

const orders = [
  { id: 1, status: "paid", total: 90, customer: { city: "Lisbon" } },
  { id: 2, status: "open", total: 40, customer: null },
  { id: 3, status: "paid", total: 120, customer: { city: "Berlin" } },
];

// 1) Safe city read with a default — fill in the operators
const cities = orders.map(o => o.customer?.city ___ "Unknown");
console.log(cities); // ✅ Expected output: [ 'Lisbon', 'Unknown', 'Berlin' ]

// 2) Group by status — fill in the method
const byStatus = Object.___(orders, o => o.status);
console.log(Object.keys(byStatus)); // ✅ Expected output: [ 'paid', 'open' ]

// 3) Highest-value paid order — fill in the array method
const topPaid = byStatus.paid.___((a, b) => b.total - a.total)[0];
console.log(topPaid.id); // ✅ Expected output: 3

// 4) Validating Proxy for config — reject negative discount
const config = new Proxy({}, {
  set(t, k, v) {
    if (k === "discount" && v < 0) throw new RangeError("no negative discount");
    return Reflect.___(t, k, v);
  },
});
config.discount = 10;
console.log(config.discount); // ✅ Expected output: 10

Notice how four separate lessons cooperate: ?. + ??, Object.groupBy, the immutable toSorted, and a validating Proxy with Reflect.set.

✅ Run the Finished Utility

Here is the completed solution as one runnable program, plus a template-literal report at the end. Run it to confirm every piece works together.

📝 Checkpoint Quiz

Answer each in your head, then reveal to check.

The nullish coalescing operator ??. Unlike ||, it only falls back for null and undefined, so a real 0 is preserved.

sort mutates the array in place; toSorted returns a new sorted array and leaves the original untouched.

Object.fromEntries(Object.entries(obj).map(...)) — convert to pairs, map them, then rebuild.

Symbol.for returns the same shared symbol from the global registry every time, while Symbol("x") always creates a new, unequal symbol.

Call Reflect.set(target, key, value) and return its result — that performs the default assignment and returns true.

JavaScript refuses to mix BigInt and Number. Convert first: 10n + BigInt(5) or Number(10n) + 5.

Pitfalls to Avoid

Quick Reference — Pick the Right Tool

NeedReach for
One matching itemfind
Safe nested read?. + ??
Bucket by keyObject.groupBy
Cross-cutting validationProxy + Reflect
Exact huge integerBigInt

📚 Keep Learning

🎉 Checkpoint Complete — Modern JavaScript!

Practice quiz

Which operator keeps a value of 0 but replaces undefined?

  • || (logical OR)
  • ?. (optional chaining)
  • ?? (nullish coalescing)
  • && (logical AND)

Answer: ?? (nullish coalescing). ?? only falls back for null and undefined, so a real 0 is preserved; || would replace it.

What is the difference between sort and toSorted?

  • sort mutates in place; toSorted returns a new array
  • They are identical
  • toSorted mutates; sort returns a copy
  • toSorted only works on numbers

Answer: sort mutates in place; toSorted returns a new array. sort reorders the original array; toSorted leaves it untouched and returns a sorted copy.

What does Object.fromEntries(Object.entries({a:1,b:2}).map(([k,v]) => [k, v*10])) produce?

  • {a:1, b:2}
  • [[a,10],[b,20]]
  • {a:11, b:12}
  • {a:10, b:20}

Answer: {a:10, b:20}. entries to pairs, map each value times 10, then fromEntries rebuilds: {a:10, b:20}.

Why use Symbol.for("x") instead of Symbol("x")?

  • Symbol.for is faster
  • Symbol.for returns the same shared symbol every time
  • Symbol("x") is deprecated
  • There is no difference

Answer: Symbol.for returns the same shared symbol every time. Symbol.for pulls from a global registry, so equal keys match; Symbol("x") always makes a new unequal symbol.

Inside a Proxy set trap, how do you perform the actual write?

  • return Reflect.set(target, key, value)
  • target[key] = value
  • return true
  • delete target[key]

Answer: return Reflect.set(target, key, value). Reflect.set forwards the default assignment and returns the boolean the trap must return.

What happens when you evaluate 10n + 5?

  • 15n
  • 15
  • It throws a TypeError
  • "105"

Answer: It throws a TypeError. JavaScript refuses to mix BigInt and Number; convert first, e.g. 10n + BigInt(5).

What does Object.groupBy(orders, o => o.status) return for statuses paid, open, paid?

  • An array of statuses
  • An object keyed by status with arrays of orders
  • A Set of statuses
  • A Map of counts

Answer: An object keyed by status with arrays of orders. Object.groupBy buckets items into an object whose keys are the returned group strings.

Which array method returns the FIRST element matching a condition?

  • filter
  • some
  • map
  • find

Answer: find. find returns the first matching element (or undefined); filter returns all matches as an array.

After Object.freeze({a:1}), what does assigning obj.a = 2 then reading obj.a give (non-strict)?

  • 2
  • 1
  • undefined
  • It throws

Answer: 1. freeze blocks the write; the value stays 1 (the assignment is silently ignored in non-strict mode).

What does [1, 2].flatMap(n => [n, n * 2]) produce?

  • [[1,2],[2,4]]
  • [1, 2, 4]
  • [1, 2, 2, 4]
  • [2, 4]

Answer: [1, 2, 2, 4]. flatMap maps each element to an array then flattens one level: [1, 2, 2, 4].

Continue this course

Frequently asked questions

What does this checkpoint cover?

It pulls together the modern JavaScript track: template literals, optional chaining and nullish coalescing, the essential array methods, object methods, symbols, getters and setters, Proxy and Reflect, and BigInt. The build challenge combines several of them in one realistic utility.

How should I use the build challenge?

Try the starter version first, filling in the blanks yourself. Run it, read the errors, and iterate. Only open the full solution once you have made a genuine attempt — comparing your working code to the reference is where most of the learning happens.

Do I need to memorize every method?

No. The goal is to recognize which tool fits a problem — find for one item, filter for many, ?? for safe defaults, a Proxy for cross-cutting validation. You can always look up exact signatures; what matters is reaching for the right concept.

Related lessons