- Control Structures
- General definition
- Branching
- Grouping
- Exception handling
- Iteration
- Arbitrary Jumps
- The Iterable and the Iterator Protocol
- Preliminary Practice
- Exercises
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:
- analyze the current state of the program
- operate on that state
- produce a result (which might or might not change the state depending on the executed operations)
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) don'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:
Take one or another direction depending on a choice
- if...else
- switch
- break
- short-circuit ( although it's an expression, it really worth it to mention here )
- conditional-operator ( a.k.a. ternary operator )
Grouping / lexical scope delimiting
Remember JavaScript prior to ECMAScript2015 (ES6) doesn't have block scope.
- do...while
- for
- for...in
- for...of
- for await...of We won't see this one yet ;)
- while
- continue
- labels yup, js has labels (-‸ლ)
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?
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
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:
done
(boolean)
- Has the value
true
if the iterator is past the end of the iterated sequence. In this case value optionally specifies the returnvalue
of the iterator.- Has the value
false
if the iterator was able to produce the next value in the sequence. This is equivalent of not specifying thedone
property altogether.value
- any JavaScript value returned by the iterator. Can be omitted whendone
istrue
.The
next
method always has to return an object with appropriate properties includingdone
andvalue
. If a non-object value gets returned (such asfalse
orundefined
), 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:
Now let's have some time to practice with some available resources online.
Here a list of resources we can use:
- W3resources conditional statements and loops exercises with solution
- EXL Skills - Conditional statements
- EXL Skills - Loops
Let's open our test files:
Now open your terminal.
- Make sure you're at the project location
- If you didn't install all the packages yet then run
npm i
for a fresh dependency install, ornpm ci
for an installation based on the lock file. - 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 ;)
Go back to DAY 4 or Go next to DAY 6