1 — Modules, Functions and Types
Get to know each other, and ensure everyone has the course projects installed properly.
Types and Operators
EXERCISE: Two Kinds of Color
Using a property descriptor, define a property on an object that’s derived from other values. We should be able to get and set this property just as if it were value based, and the getter and setter you define should keep all of the dependencies in sync properly.
EXERCISE: Refactoring into Modules
Take a solution from the previous exercise and refactor it, so that the heavy lifting is done by two pure functions in a separate module.
EXERCISE: Functional Cart
Build a shopping cart that takes advantage of a closure’s ability to hold state (and functions defined within that closure to access that state).
Break for lunch
2 — Working with Data
EXERCISE: Map, Filter, Reduce
Using our knowledge of how higher order functions on the Array prototype work, we’ll implement our own map, filter, reduce and forEach functions.
Control flow statements like
switch give us the ability to define various paths that our program can take, under different circumstances. We’ll look at how these work in detail, including some non-traditional (but very useful) use cases.
EXERCISE: Versioned Documents
Progressive Web Apps often need to store data in some durable medium. It’s a good idea to version long-living data since old data may need to work with new versions of the application. We’ll use our newfound knowledge of control flow statements to “upgrade” a versioned data structure to the current version, so that the rest of our app need not worry about it.
Loops and Iteration
While you’re no doubt familiar with a
for..of loops, and refresh ourselves with often-forgotten concepts like
EXERCISE: Fibonacci Numbers
Implement a function that returns a Fibonacci sequence of a specified length. Ensure that your solution works for sequences up to 10 million numbers long!
Wrap up and recap
We’ll recap all the ground we’ve covered today, and set our sights on tomorrow’s agenda.
3 — Handling Asynchrony
We’ll recap everything we’ve covered so far, and review today’s agenda.
Promises can be thought of as “eventual values”, and are a great abstraction of some asynchronous work. We’ll review basic promise usage, error handling, and techniques for grouping promises together in sequence or in parallel.
PROJECT: Fetch Coalescing
Often, when a single page app boots up, requests for remote data at various URLs will be sent out as part of the startup process. Occasionally, we can see multiple requests going out for the exact same resources. We’ll build a utility that ensures that request for data that’s already on its way are link together and resolved by the same promise.
Iterators and Generator Functions
PROJECT: Async Task Runner
One of the most powerful things we can build on top of generator functions is an “async task runner”. You have an “autocomplete” use case already set up, that involves running several async operations in sequence.
Async and Await
Now that we’ve done all the work to build a task function, we’re in a perfect position to appreciate a new language feature that looks very similar:
await keyword, when used in an
async function, allows us to write asynchronous code in a way that looks and feels very much like the synchronous (blocking) equivalent!
EXERCISE: Write an Integration Test
Integration tests are a perfect place to use
await, because we often want to perform a series of simulated user interactions and wait for each one to complete, before proceeding further in the test.
Break for lunch
4 — Advanced Data Structures
Maps and Sets
Set are new data structures that have distinct advantages in various use cases. We’ll study both in detail, including their “weak” counterparts:
PROJECT: Spies and Stubs
Map, we’ll build a small “spying” library that we can use to monitor function invocations in our tests.
PROJECT: Buffered Proxy
Although there aren’t many obvious use cases for the
Proxy type, one place where it proves handy is to “stage” proposed modifications to an object, without mutating the underlying values directly. We’ll implement a “buffered proxy” utility, and use it in an “edit form” context.
Wrap up and Recap
We’ll recap everything we’ve covered today, and set our sights on tomorrow’s agenda.
5 — Classes
We’ll recap everything we’ve covered so far, and review the day’s agenda.
class doesn’t allow us to do anything that wasn’t possible with the direct use of prototypes, many things are easier and much cleaner. We’ll look at constructors, member and static functions, and the upcoming “member and instance field” TC39 proposals.
EXERCISE: Colors with classes
We’ll look back at our rgb/hex color exercises, and implement a more comprehensive solution using classes.
Decorators allow us to do things at class construction time. Several uses of decorators are possible with the current draft spec (or when using Typescript) and a variety of proposals for new decorators are already in development!
PROJECT: Memoized functions
Memoization is a technique that can be used with pure functions, where output values are “remembered” for an input argument(s). Thus, re-invoking the function with the same arguments will return the same “remembered” result. We’ll implement a
@memoize function decorator, so that we can apply this technique easily and cleanly in our code.
While it’s true that
PROJECT: Design Patterns w/ Class
We’ll implement some examples of classical object-oriented design patterns using
Break for lunch
6 — Performance & Tooling
Advanced Debugging Tools & Techniques
Chrome and Node.js have recently undergone major advancements in their debugging tools. We’ll learn how to make the most of these tools, and demonstrate how life is now a little easier when it comes to debugging async code, or long chains of promises.
EXERCISE: Finding and fixing a few pesky bugs
We’ll eradicate some bugs that would traditionally be very difficult to identify and track down.
We’ll learn about the new performance audits, how to read and act on the results of a flame chart, and how to instrument a piece of code so that you get accurate and consistent results.
EXERCISE: Measure and Improve Key Metrics
You’ll be given a few functions that can be substantially optimized. Measure them, identify the slow parts, and make a quantifiable improvement!
High level architecture of a modern JS runtime
We’ll take a quick look at the architecture of the V8 Runtime that ships with Google Chrome and Node.js. In understanding how V8 Runtime works and how it tries to speed up our code, we’ll learn about patterns we need to avoid.
EXERCISE: Finding and fixing de-optimizations
Wrap up and Recap
Our final rap up with a full-course recap, suggested reading and learning to take this new knowledge further!