About this course
Production Architecture: prototypal inheritance and true private fields, Proxies, Reflect and Symbols, the microtask event loop and weak-reference memory management, through to Promise combinators, async generators, custom event systems and Web Worker concurrency - five modules, one Compiler Quest per topic.
This is a 6-week short course - enough depth to build real projects and a portfolio piece, without a long commitment. Learn online at your own pace. Practice the concepts with the listed assessments.
What's included
- Self-paced lessons and practice (15 estimated hours).
- Hands-on coding quests you solve inside the EchoLens browser compiler - nothing to install.
- Gems, stages and a leaderboard that keep you moving instead of grade anxiety.
- A verified certificate with a scannable QR code, ready to share on LinkedIn, when you satisfy the course requirements.
- Completely free - no fee, just create an account and start.
What you will learn
Course outline - level by level
15 leveles, each with hands-on quests you clear in the portal.
- Level 1. Prototypal Inheritance & the Prototype Chain - Real-life analogy: Think of a hereditary royal lineage. If a young prince does not personally own a particular castle, the court checks his father the king, then the grandfather, on up the family tree to the founding monarch (Object.prototype). Every JavaScript object holds an internal [[Prototype]] link (readable via Object.getPrototypeOf() or __proto__). When a property lookup misses on an object, the engine follows that link to the next object, and the next, until it either finds the property or reaches null.
- Level 2. Function Constructors vs ES6 Classes & #private Fields - Real-life analogy: Think of a high-security briefcase. Its outer pockets are open for anyone to inspect, but the inner vault (#private) is sealed behind a hardware lock that cannot be picked from outside. ES6 class syntax is sugar over the prototype system. A field declared with a # prefix is a hard private field enforced by the engine itself: it is invisible to Object.keys, JSON.stringify and reflection, and touching it from outside the class is a syntax error.
- Level 3. Property Descriptors (Object.defineProperty, freeze, seal) - Real-life analogy: Think of notarising a legal contract with tamper-evident wax seals: individual clauses can be marked read-only (writable: false) or non-removable (configurable: false), or the whole document can be locked shut (Object.freeze). Every property has a descriptor - value, writable, enumerable, configurable. Object.seal() stops keys being added or removed but leaves values editable; Object.freeze() locks the whole object so existing values cannot change either.
- Level 4. Proxy Traps (get, set, deleteProperty) - Real-life analogy: Think of a diplomatic security attache who intercepts, inspects and validates every package and courier before letting any of it through the embassy gate. A Proxy wraps a target object and intercepts fundamental operations through traps: get for reads, set for writes, deleteProperty for deletions, apply for calls. A trap can validate, transform, log or reject the operation before (or instead of) letting it reach the target.
- Level 5. Reflect API & Transparent Forwarding - Real-life analogy: Think of a universal remote-control protocol: whatever brand of television you point it at, the standard commands - power, volume, input - forward through cleanly without any vendor-specific quirks. The Reflect API exposes the interceptable object operations as plain functions - Reflect.get, Reflect.set, Reflect.has, Reflect.deleteProperty - with predictable return values. Inside a Proxy trap, calling the matching Reflect method is the correct way to perform the default behaviour while preserving the receiver.
- Level 6. Well-Known Symbols (Symbol.iterator, Symbol.toPrimitive) - Real-life analogy: Think of the standard markings stencilled on a shipping container. The barcode (Symbol.iterator) tells any crane in any port how to unload it, without the crane needing to know what is inside. Symbol() creates a guaranteed-unique key. The well-known symbols - Symbol.iterator, Symbol.toPrimitive, Symbol.hasInstance - are hooks the engine already looks for, so defining them on your class overrides how for...of, coercion and instanceof behave for its instances.
- Level 7. Microtasks vs Macrotasks (queueMicrotask, MutationObserver) - Real-life analogy: Think of a bank teller. They call the next ticket from the lobby (a macrotask), but before calling another ticket they must first finish every piece of desk paperwork already in front of them (the microtasks). The event loop runs one macrotask (a setTimeout / setInterval callback, an I/O event), then drains the entire microtask queue (Promise callbacks, queueMicrotask) before it will paint or take the next macrotask. So a promise callback always runs before a setTimeout(fn, 0) queued at the same time.
- Level 8. WeakMap & WeakSet (Memory Leak Prevention) - Real-life analogy: Think of a coat-check tag. While you are in the building the tag ties your ticket to your coat; once you leave for good the tag is discarded on its own - it never keeps your coat hostage. A WeakMap keys entries by object, and holds those keys weakly: when nothing else references a key object, the entry is garbage-collected automatically. WeakMap/WeakSet are not enumerable and have no size - which is exactly what makes them safe for DOM node metadata and private caches.
- Level 9. FinalizationRegistry & Garbage Collection Mechanics - Real-life analogy: Think of leaving instructions with a will executor: "when this particular antique safe is finally demolished by the city, file a notice in the municipal archive." A FinalizationRegistry lets you register a cleanup callback that may fire after an object has been reclaimed by the garbage collector, receiving a held token you chose. Paired with WeakRef, it is how you release external resources - file handles, sockets, native buffers - tied to a JavaScript object's lifetime.
- Level 10. Promise Combinators (all, allSettled, race, any) - Real-life analogy: Think of an election news desk tracking four districts. Promise.all needs every district to report and fails if one collapses; Promise.any calls it the moment the first result lands; Promise.allSettled publishes the full audit of every district, wins and failures alike. Promise.all() is fail-fast parallel, Promise.allSettled() reports the outcome of every input regardless of rejections, Promise.race() settles as soon as the first input settles (fulfilled or rejected), and Promise.any() resolves with the first fulfilment.
- Level 11. AbortController & Request Cancellation - Real-life analogy: Think of the "Cancel Print" button on a 500-page press: one press and the job stops mid-run, before it wastes any more paper. An AbortController produces an AbortSignal you pass into fetch(), an event listener, or your own async work. Calling controller.abort() rejects the pending operation with an AbortError, which is how you stop stale requests when the user navigates away or types a new query.
- Level 12. Async Generators & for-await-of - Real-life analogy: Think of streaming a series instead of downloading the whole season first - each chunk arrives and plays as it lands, and you can stop watching at any point. An async generator (async function*) yields values that are themselves awaited, so it can pause for I/O between items. It is consumed with for await (const item of stream), which pulls one item at a time and never buffers the whole sequence in memory.
- Level 13. Custom Event System (CustomEvent & EventTarget) - Real-life analogy: Think of a stock-exchange bell. When the index hits a record the exchange rings it once (dispatches an event); every broker tuned to that signal reacts on their own, and the exchange never needs to know who is listening. EventTarget and CustomEvent give you publish/subscribe with no framework: addEventListener registers a handler, and dispatchEvent(new CustomEvent(name, { detail })) fires it with a payload, keeping the emitter and the listeners fully decoupled.
- Level 14. Multithreading with Web Workers (postMessage, onmessage) - Real-life analogy: Think of a restaurant manager hiring an accountant in an upstairs office. The manager keeps greeting guests at the door (the UI thread) while the accountant crunches the tax spreadsheets in the background (the worker thread). A Web Worker runs a script on its own thread, isolated from the main thread and the DOM. The two sides communicate only by structured-clone message passing - postMessage() to send, an onmessage handler to receive - so heavy computation never blocks rendering.
- Level 15. SharedArrayBuffer & Atomics (Thread Synchronization) - Real-life analogy: Think of one physical whiteboard in a shared room. Instead of photographing notes and emailing copies, every worker writes on the same board - and follows an atomic marker rule so two people never overwrite the same spot at once. A SharedArrayBuffer is real memory shared between the main thread and workers with no message-copy overhead. The Atomics object provides the safe operations on it - Atomics.add, Atomics.load, Atomics.wait, Atomics.notify - that make concurrent reads and writes race-free.
How you submit: Coding quests solved in the built-in EchoLens compiler.
Who it's for
Advanced JavaScript Programming suits learners at a beginner to intermediate level who want a practical, project-based route into Advanced JavaScript Programming. You need only a browser and an internet connection - all coding runs inside the EchoLens compiler, so there is nothing to set up.
Certificate
Pass every required assessment at its stated threshold to earn your verified certificate. Optional practice and watching videos do not determine eligibility. Anyone can scan its QR code to verify it on our site. You can add it to your CV or share it to LinkedIn in one click.