
This course includes our updated coding exercises so you can practice your skills as you learn.
See a demo
Master advanced JavaScript concepts from closures and currying to prototypes and private class fields. Explore built-in APIs like performance, WebSocket, web storage, geolocation, and notifications to deepen your proficiency.
Explore advanced JavaScript concepts from object oriented programming with classes and this to asynchronous patterns, browser APIs, solid principles, and design patterns, all organized as a candy shop curriculum.
Download the course code: each section includes a zip with its files, or download one full zip for all sections, then unzip to access topic folders like timers and debouncing.
Master a practical development setup with Visual Studio Code and Live Server extension, using index.html and app.js to see real-time changes in the browser.
Explore how plain old JavaScript objects act as key-value stores with stringified keys, and how to access data via dot and bracket notation to create methods.
Explore mixing data with functions inside a JavaScript object, creating methods for triangle area and hypotenuse, and why this pattern isn’t scalable without classes.
Explore JavaScript classes as blueprints for reusable objects, instantiate them with the new keyword, and access shared methods like get area and get hypotenuse across distinct instances.
Learn how a constructor initializes a triangle's sides, uses the new keyword to create instances, and validates input to ensure A and B are numbers for accurate area calculations.
Design a bank account class with account number, account holder, and a zero-default balance; implement deposit and withdraw methods with balance updates and basic validation.
Explore how instance methods operate within JavaScript classes, using this to access instance properties and to call other methods like get area, as shown in a triangle example.
Learn how inheritance in JavaScript uses extends to let a child class reuse a parent class's methods like get area and get hypotenuse, while overriding describe.
Explore how to use super to call a parent constructor when extending a class, add new properties like color, and access inherited methods such as get area and get hypotenuse.
Learn how static properties and static methods attach to the class, not instances, as shown with a Cat class where Cat.species is shared by all cats.
Discover how static methods attach to the class itself rather than instances, use the class name to call them, and how this refers to the class in JavaScript.
Use static methods to group related functionality in a class and to create new instances via factories, as shown by a math object and a Jobfinder API.
Learn how getters and setters simplify object oriented patterns in JavaScript, using the get keyword to treat derived values like diameter as properties and reveal behind the scenes logic.
Master setters in JavaScript by intercepting property updates with the set keyword, validating radius and color through getters, underscore privacy, and static allowed colors.
Define a person class with first and last names, create a full name getter to combine them using dot notation, and a setter that splits a string to update both.
Master public class fields in JavaScript, compare them with static and private fields, and see how default instance properties can be declared up top for clarity.
Master private class fields in JavaScript (ES2021) using a hash prefix to encapsulate a radius; access via a getter, while outside access remains blocked.
Define private methods in JavaScript with a pound symbol to restrict access to inside the class, enabling internal calls via this method while preventing external invocation.
Explore ES2022 static initialization blocks that run once when the class is loaded, enabling complex initialization of static properties such as choosing production or development connections via environment variables.
Master the this keyword in JavaScript, and learn how call and bind reassign its value and affect this in methods versus stored functions.
Explore how this behaves differently in plain objects versus class methods, using a Cat example to show this.firstName access and errors when a method is stored in a variable.
Discover how this varies with the object a function is called on, and how global objects like window or global shape the behavior of methods such as console.log.
Explore how the this keyword is dynamically determined by how a function is called, often equal to the left-hand object on the dot, such as window or a custom object.
Explore how this behaves in classes and instances, including static methods and isolated method calls, and how this can become the class, the instance, undefined, or the window.
Learn how the call method explicitly invokes a function on a chosen object, sets this to that object, accepts arguments, and lets methods be reused across objects.
Explain how the apply method binds this and passes arguments from an array-like object. Compare it with call, demonstrate Math.max with arrays, and note spread as a modern alternative.
Use bind to permanently bind a function to a specific context, creating a new function with this fixed to that context, avoiding undefined this and repeated binding.
Explore how bind bakes in arguments and optionally the context, producing new function copies (like California sales tax or double) that always apply preset values.
Bind with event listeners explains how this is determined in callbacks passed to addEventListener, and how bind permanently sets this to a specific object for a button click.
Learn how to bind this in a timer callback by using a counter class with setInterval, fixing window as this, and comparing binding in place vs extracting a method.
Learn how arrow functions handle the this keyword, showing they don’t create a new this, preserve the cat instance in setTimeout, and reduce the need for bind in many cases.
Explore how the keyword this depends on execution context, and use bind or arrow functions to preserve this in callbacks, timeouts, and event listeners.
Explore object oriented JavaScript behind the scenes, including prototypes, constructor functions, and the new keyword, and see how the class keyword sits as syntactic sugar over prototypal inheritance.
Learn how the new keyword in JavaScript creates a new object, binds this to it, and returns that object when using constructor functions or the class keyword.
Explore how classes differ from constructor functions in JavaScript, showing how prototypes share methods like bark and sleep across all dog instances to optimize memory.
Explore how prototypes let JavaScript objects share methods through a prototype. The class keyword attaches instance methods to the prototype; arrays and dogs share behavior through the prototype chain.
Explore how JavaScript prototypes share methods like bark and sleep across all dogs, using the new keyword to create objects linked to a dog prototype, with constructor references.
Explore how the prototype chain links objects from child to parent to grandparent, enabling access to properties and methods through successive prototypes.
Explore constructor functions and prototypes, then see how classes simplify definitions by placing methods on the prototype, and how extends and super enable prototype-based inheritance across a chain.
Shows the difference between the function prototype and the __proto__ property, with dog.prototype providing methods like bark and sleep for instances, while __proto__ remains internal and should not be touched.
Explore JavaScript prototype concepts with Object.create to set a prototype, learn Object.getPrototypeOf and Object.setPrototypeOf, and use isPrototypeOf to inspect prototype chains.
Explore how callbacks drive asynchronous behavior in JavaScript, with examples of setTimeout, setInterval, event-driven code, array methods like map, filter, and reduce, and how promises and async/await offer cleaner patterns.
Explain why JavaScript's single-threaded model requires asynchronous patterns like callbacks, promises, and async/await. Highlight callback hell and the pyramid of doom, and point to modern solutions.
Master promises as a structured alternative to callbacks, learn their three states—pending, resolved, and rejected—using fetch and the Pokemon API to write cleaner, error-aware async code.
Master promises with then and catch to handle resolved data and errors from fetch, log responses, and chain promises to avoid callback hell.
Master promise chaining to flatten callback hell by performing four sequential fetches, returning promises and chaining thens for a flat, readable flow with catch-based error handling.
Apply a single catch at the end of a promise chain to handle any rejection, including fetch, and achieve cleaner, flatter asynchronous code.
Master async and await in JavaScript to simplify promises, declare async functions, and pause execution with await, using fetch examples to show non-blocking, synchronous-like code.
Learn how to use async/await to perform four fetch calls in series within an async function, pausing until each promise resolves, and understand promises, error handling, and syntactic sugar.
Master how to handle errors in async functions using try and catch, catching rejected promises with a single try-catch. Explore practical examples with fetch and robust error handling.
Compare then and catch with async and await to handle parallel async operations using multiple fetch calls, and learn when to use promise objects directly versus async/await.
master running asynchronous operations in sequence using promises and async/await to fetch resources one, two, and three in order, building a results array with clear, readable flow.
Combine multiple asynchronous operations with Promise.all to run an array of promises in parallel and resolve when all succeed. Use async/await to log results and catch any rejection.
Master asynchronous patterns with promise.all settled to wait for all promises, then separate fulfilled and rejected results.
Learn how Promise.race races a batch of promises, resolving or rejecting as soon as the first one settles, returning a new promise from an array of fetch calls.
Learn to create custom promise objects with new Promise and the resolve and reject functions. Promisify callback-based code, use async/await or then, and control timing with setTimeout examples.
Learn how to convert Node's callback-based fs.readFile into promises, implement promise chaining and async/await for cleaner, error-handled file reads.
Learn how optional chaining simplifies accessing nested properties in JavaScript, preventing errors from undefined values when reading user data like name, address, coordinates, and optional greet methods.
Master the nullish coalescing operator, which returns the right-hand value only when the left is null or undefined, preserving zero or false values while assigning defaults during object access.
Explore numeric separators in JavaScript by using underscores to group digits in large numbers, improving readability without changing the value, as shown with 8 million and 900 billion.
Discover the array method at, which returns the element at a given index and supports negative indices to count from the end, unlike square brackets.
Master the string replaceAll method to replace every occurrence in JavaScript, using plain strings or regex with global and optional case-insensitive flags.
Learn how the logical or assignment ||= works by updating an object's properties with short-circuit evaluation, assigning a fallback value only when the left side is falsy.
Explore the logical and assignment operator &&=, updating a value only when the left side is truthy through short-circuiting, illustrated with a logged-in user’s color preference.
Demonstrate the nullish coalescing assignment operator, updating a variable only when it is null or undefined, preserving zero and empty strings, unlike the logical or assignment.
Explore promise.any by comparing it to race, showing how it resolves with the first fulfilled promise from an iterable, and only rejects if all of them reject.
Discover new OOP features in JavaScript, including private fields using the hash syntax, public fields, private methods, and static initialization blocks that run once when the class loads.
Explore JavaScript's single number type and floating point imprecision, including why 0.1 plus 0.2 may not equal 0.3. Use an epsilon-based helper to compare floats and manage precision.
Learn how JavaScript uses BigInt to handle very large integers, surpassing max safe integer and avoiding precision loss caused by floating point limits, via BigInt() or literals ending in n.
Explore how not a number (NaN) arises in JavaScript from 0/0 or invalid string coercion, and compare isNaN with Number.isNaN to determine when a value is not a number.
Master pre-increment and post-increment in JavaScript, using ++x and x++, and compare their expressions with post and pre decrement operators like x-- and --x.
Explore automatic semicolon insertion in JavaScript and how line breaks and editor behavior can affect return statements and object literals. See why using semicolons consistently helps prevent subtle runtime errors.
Explore how JavaScript generator functions pause and resume execution to yield values on demand, with next returning an object containing value and done.
Show how a generator yields batches of image URLs from a large array, enabling incremental loading in infinite scroll by default ten per batch and using next to fetch more.
Explore the versatile array.from method, turning iterables such as strings, sets, and node lists into arrays, using a mapping function and length to generate sequences.
Explore JavaScript scope and hoisting, from global and function scope to block scope, and compare var with let and const as it relates to closures.
Explore how let and const differ from var in scope, showing var adds to window and risks collisions, while let and const are block- and function-scoped and not on window.
Explore the scope chain in JavaScript, tracing variable lookup from local scopes through outer functions to the global scope, including block and nested function behavior and closures.
Explore how JavaScript uses static lexical scoping, not dynamic scope, and see how variable scope is determined at declaration through an example with print animal and a global animal.
Explore hoisting in JavaScript, where var declarations move to the top of their enclosing scope and initialize to undefined, while let and const trigger a temporal dead zone until initialization.
Discover immediately invoked function expressions (IIFEs) and how wrapping a function in parentheses and invoking it protects privacy, avoids global scope pollution, and prevents name conflicts.
Explore closures in JavaScript by defining a function inside another function that accesses outer variables, returning the inner function to preserve scope and enable persistent data across calls.
Discover closures by creating a counter with a private variable, exposed via an object of methods like increment, decrement, and get count, using an immediately invoked function expression.
Explore how closures drive factory functions that produce specialized tools, like exponent creators and unique id generators, preserving private variables and prefixes through the scope chain.
Explore how closures manage per-button state in event listeners using an immediately invoked function expression and a create counter button pattern. Each button maintains its own count without global variables.
Explore closures in loops with setTimeout, showing how var loses the loop value and how let or an immediately invoked function expression preserves it.
Master JavaScript timers with setTimeout and related APIs, learning basic syntax and delays in milliseconds, including setInterval, clearTimeout, recursive timers, throttling, debouncing, and requestAnimationFrame.
Explore setInterval, a built-in window function that repeats a function at a fixed delay, and build a simple countdown timer that updates an on-page element every second.
Learn how to stop a running interval by capturing the interval id from setInterval and using clearInterval to halt the countdown and display time is up.
Learn how clear timeout cancels a scheduled function by using the timeout ID returned from setTimeout, with practical examples like canceling a 5-second redirect and debouncing.
Debouncing prevents excessive function calls by delaying execution after user input. In a live search, it waits for typing to pause before querying the api.
Create a reusable debounce higher-order function that takes a callback and delay, returning a debounced wrapper that clears timeouts, delays calls, and passes through any arguments to the callback.
Master throttling to limit function execution during events like scrolling, ensuring only one call per interval and reducing API load; compare with debouncing for delayed execution.
Explore a fancier, reusable higher-order throttle function that ensures the callback runs at most once per delay, handling saved arguments and is-throttled state for scroll events like loading more items.
Learn how requestAnimationFrame powers smoother, more performant animations by syncing with the next browser paint, compare it to setInterval, and implement frame-based rotation for visuals.
Discover how requestAnimationFrame passes a high-resolution timestamp to its callback, letting you measure elapsed time between frames and drive smooth, one-second animations with precise timing.
Master the smooth scroll to top using requestAnimationFrame, time stamps, and a one-second animation that computes start, end, and progress to update the vertical scroll with a performant frame-by-frame loop.
Transform your basic JavaScript knowledge into expert-level skills with this brand-new comprehensive course designed for those ready to take the next big leap in their programming career. If you've ever found yourself intimidated by JavaScript's more complex features or struggled to grasp its intricate concepts, this course is tailor-made for you. If you've taken a few Udemy courses on JavaScript and don't know where to go next, this course is for you!
This course demystifies the 'scary' and tricky parts of JavaScript, guiding you through the intricate details and advanced aspects with ease. By the end of this journey, you'll not only understand these concepts but also skillfully apply them in real-world scenarios.
Key Topics Covered:
Object-Oriented Programming (OOP): SOLID design principles, prototypes, private class fields, etc.
JavaScript Design Patterns: Proxy objects, module pattern, singleton pattern, observer pattern, mixin pattern, registry pattern, and others.
Advanced JavaScript APIs: IndexedDB, Geolocation, Web Sockets, Notifications API, Canvas, getUserMedia, and more.
'this' Keyword Mastery: Deep dive into 'this', call, apply, and bind methods.
Asynchronous Programming: Master promises, async/await, asynchronous design patterns, and write your own promise objects
Modern JavaScript Features: Optional chaining, nullish coalescing, logical assignment operators, and other ES2021 & ES2022 features
Tricky Parts of JavaScript: Tackle closures, float imprecision, BigInt, automatic semicolon insertion and a bunch more.
Functional Programming Techniques: Recursion, currying, composition, partial application, and more.
Whether you're a self-taught programmer, a computer science student, or a professional developer looking to sharpen your JavaScript skills, this course will elevate your coding abilities, preparing you to handle advanced web development challenges with confidence and expertise.