A walk in JavaScript

DAY 5

Control Structures

As we saw in DAY 1, JavaScript is as multi-paradigm language. One of this paradigms is the imperative one which requires the program to instruct the machine how to change its state, and the order in which individual statements and instructions are executed or evaluated.

There are several definitions out in the wild and they will vary depending on the context and the language. One I found very simple and educative is the following:

A control structure is a block of programming that analyses variables and chooses a direction in which to go based on given parameters. The term flow control details the direction the program takes (which way program control “flows”). Hence it is the basic decision-making process in computing; It is a prediction.

Source: Wikiversity

Also there we’ll find a great enlightment of the whole picture of a control statement.

Those initial conditions and parameters are called preconditions. Preconditions are the state of variables before entering a control structure. Based on those preconditions, the computer runs an algorithm (the control structure) to determine what to do. The result is called a post condition. Post conditions are the state of variables after the algorithm is run.

Source: Wikiversity

Now it’s clear that a control structure will:

Although function construct, and asynchronous routines like async/await, promise and timers like setTimeout are ways of making decisions and changing the state of a the program, they’re not strictly considered control structures. That said, they’re so important to know that we’re going to see them in the next days.

Note that some languages require a final keyword whilst JavaScript (and others) doesn’t. ( See here )

It’s also interesting to note that “Control Structures” or “control Flow” is not part of the organization of the ECMAScript standard, it rather organizes them in terms of statements which make total sense, as it’s the spec of the language and not a programming manual.

Let’s start with organizing them:

Branching

Take one or another direction depending on a choice

Grouping / lexical scope delimiting

Remember JavaScript prior to ECMAScript2015 (ES6) doesn’t have block scope.

Exception handling

Iteration

Arbitrary jumps

The Iterable and the Iterator Protocol

Until ES6, all iteration adhered to the run-to-completion model where essentially there was no mechanism to pause/resume a loop. You could interrupt it or wait until the iteration finished, but no granular control over the iteration steps pace was possible. In order to evolve, many of the features introduced in ES6 where protocols, and some of the existing features started using them under the hood to be both backwards compatible and scalable for the future.

Here is how ECMAScript spec defines them:

But they might be a little harsh at this moment, why don’t we take a look at MDN for a friendlier description?

Iterable Protocol

The iterable protocol allows JavaScript objects to define or customize their iteration behavior, such as what values are looped over in a for..of construct. Some built-in types are built-in iterables with a default iteration behavior, such as Array or Map, while other types (such as Object) are not.

In order to be iterable, an object must implement the @@iterator method, meaning that the object (or one of the objects up its prototype chain) must have a property with a @@iterator key which is available via constant Symbol.iterator

Source: MDN - The iterable protocol

Iterator Protocol

The iterator protocol defines a standard way to produce a sequence of values (either finite or infinite), and potentially a return value when all values have been generated.

An object is an iterator when it implements a next() method with the following semantics:

Property: next

Value A zero arguments function that returns an object with at least the following two properties:

The next method always has to return an object with appropriate properties including done and value. If a non-object value gets returned (such as false or undefined), a TypeError (“iterator.next() returned a non-object value”) will be thrown.

Source: MDN - The iterator protocol

Essentially this protocols defines and interface to iterate in a consistent way across implementations opening the door for you to define your own iterables taking control of the iteration steps in a super granular way.

Also a big section of the Chapter 3 of Your Don’t Know Js - ES6 & Beyond is dedicated to iterators. Let’s read how it starts:

An iterator is a structured pattern for pulling information from a source in one-at-a-time fashion. This pattern has been around programming for a long time. And to be sure, JS developers have been ad hoc designing and implementing iterators in JS programs since before anyone can remember, so it’s not at all a new topic.

What ES6 has done is introduce an implicit standardized interface for iterators. Many of the built-in data structures in JavaScript will now expose an iterator implementing this standard. And you can also construct your own iterators adhering to the same standard, for maximal interoperability.

Source: YDKJS - ES6 & Beyond - Ch 3

We can find many iterable examples here.

Another interesting reading is “A Simple Guide to ES6 Iterators in JavaScript with Examples” by “Brandon Morelli

You might ask “what the hell are those @@?” They’re called “Well Known Symbols” and you can read more here:

Preliminary Practice

Now let’s have some time to practice with some available resources online.

Here a list of resources we can use:

Exercises

Let’s open our test files:

Now open your terminal.

  1. Make sure you’re at the project location
  2. If you didn’t install all the packages yet then run npm i for a fresh dependency install, or npm ci for an installation based on the lock file.
  3. Type npm run test:watch, this will start running your tests every time you make a change.

Our task is to make ALL our DAY 5 tests pass ;)