Stay tuned for additional content in this series.
Interactive code: When you see Run at the top of a code sample, you can run the code, check the results, make changes, and run it again.
Part 2 is dedicated to language updates that will change how you work with
definitions and call syntax, and you'll learn more about destructuring
assignment, this time in function definitions. I'll also introduce the new
arrow function syntax and generator functions, the latter of which puts an
interesting spin on the classic iterator and ye
Destructuring in function declarations
If a function is expecting an object, you can use destructuring to extract the relevant parts of that object even before the function begins. Do this by adding destructuring syntax to the function's arguments, as shown in this listing.
displayDetails function only cares about the
age fields of the object being
passed in. Adding a destructuring assignment to the object syntax
effectively extracts those values as part of the function call. The call
syntax itself remains unchanged, making it easier to refactor legacy code
to use the new syntax.
You can also use destructuring array syntax in functions, but it's less impressive than some of the other features you're about to see.
ECMAScript has made a few syntactic changes to function parameters. Specifically, it's introduced default parameter values, rest parameters, and the spread operator for function calls. As I've mentioned before, most of these are syntactic sugar over conventions that ECMAScript developers have been using for years. Now that they're full-blown language features, you can accomplish the same work using fewer lines of code.
We'll start with default parameters, probably the easiest of the three to understand.
In addition to allowing for destructuring syntax, ECMAScript 6 now offers a default parameter value syntax similar to what's found in several C-family languages. Even if you've never seen default parameters before, the syntax is fairly obvious and intuitive:
In essence: if a parameter is specified at the call site, then the parameter takes the value passed; if no value is specified, then the default value is assigned.
As with some of the updates introduced in Part 1, the new default parameter is essentially syntactic sugar. Here's how you might have coded it in prior versions of ECMAScript:
The new syntax is simply shorter and more expressive, and standardizes what many programmers have been doing for years.
One of the more common idioms in ECMAScript libraries is to define
functions or methods that take one or more fixed parameters, followed by a
collection of optional parameters that refine or modify the call in a
user-defined way. Historically, you might have done this by accessing the
arguments parameter that is silently constructed and
passed to every function call:
Using the new rest parameters syntax, you can capture the optional arguments into a local array variable. You use them the same as above, but without modification:
Notice that the rest parameter (
args in the first listing)
doesn't need to be tested for existence; the language guarantees that it
will exist as a 0-length array, even if no additional parameters are
The spread operator is in some ways the conceptual opposite of the rest parameter. Whereas the rest parameter collects a number of optional values passed in a given call, the spread operator takes an array of values and "spreads" them out, basically destructuring them to be used as individual parameters to the function being invoked.
Spread's simplest use case is to concatenate individual elements into an array:
Without the spread operator syntax, you would need to extract and append each individual element of the first array to the second array, before adding in the remaining elements.
You can also use the spread operator in function calls; in fact, that's where you'll likely use it the most:
Note that unlike the rest parameter, the spread operator is used at the point of call, not in the function definition.
Function syntax and semantics
As newer functional languages like Scala and F# have gained mainstream acceptance, older standbys have started adopting some of their shinier features. One such feature is the arrow function syntax, a symbolic shorthand used to create function literals. Starting with ECMAScript 6, you can use the so-called fat arrow (as opposed to its skinny cousin) to create function literals, like so:
If you've tried your hand at functional programming in C#, Java™ 8, Scala, or F# you're likely familiar with this syntax. Even if you're not familiar with it, the arrow is pretty easy to understand: the parentheses before the arrow capture the parameters to the function body, and the arrow itself sets off the start of the function body. If the body consists of a single statement or expression, there's no need for curly braces. If the body contains multiple statements or expressions, you can denote that by putting braces immediately after the arrow:
If there is only one parameter, you can choose to leave out the parentheses
entirely. The syntax
names.forEach(n => console.log(n));
works just fine. (Personally, I use parentheses for even a single parameter, but that's an aesthetic preference about which reasonable people can reasonably disagree.)
Also note that if the body of the arrow function is a single expression yielding a value, no explicit return is required. Instead, that single expression is implicitly returned to the arrow function's caller. If, however, the body is more than one statement or expression, the curly brackets are mandatory, and any returned value must be sent back to the caller via the usual "return" syntax.
A new definition for 'this'
Long before pen was ever put to page for ECMAScript 6, programmers have
struggled to figure out what ECMAScript's
points to. Ostensibly, as with other C-family languages,
is the parameter that references the object on which a method is being
invoked, as shown here:
The above parameter clearly references the instance
dutifully prints out the name and values of
lastName, and (since it too is a member of the object) the
Things get a little weirder when
this is referenced from a
function that exists at the global scope:
For the uninitiated, ECMAScript defines the global scope as an object, so
when used from a function in the global scope,
references the global scope object. In the case above it would dutifully
print out each member of the global scope, including top-level global
variables, functions, and objects (such as "console" in the above
Because of this, we can also reuse the function in two separate contexts, knowing that each time it will do more or less what we expect:
The syntax is a bit odd, perhaps, but not a problem as long as you understand the rules. It's not until you try using ECMAScript constructor functions as object types that things start to go really sideways:
You might expect the value of
p.age to increase by 1 after a
tenth of a second. But because the
this in the
growUp function literal refers to the global object instead
p, the value of
p.age never changes from 0.
(Normally you would have your
Person object age forever by
growUp() function with
However, the developerWorks sandbox doesn't support code that runs
indefinitely, so this example uses
Lexical 'this' binding
To resolve the definition issues associated with
functions have what's called lexical
This means that the arrow function uses the
this value at the
time the function is defined, not the time it's executed.
Perhaps the easiest way to understand the difference is with an old Node.js
standby, the EventEmitter. Recall that the EventEmitter (obtained from the
events module) is a simple pub-sub style messaging system:
You can register callbacks on the emitter on a particular event name, and
when that event is "emitted," the callback(s) are fired in the order in
which they were registered.
If you register a legacy function with the EventEmitter, the
this captured will be the one determined at runtime. But if
you register an arrow function with the EventEmitter,
will be bound at the time the arrow function is defined:
When the function events are fired,
this is bound to the
EventEmitter itself, whereas the arrow events are bound to effectively
nothing (they each print an empty object).
Generators are functions that are designed to produce a stream of values for consumption by other parties. Generators are used in a number of functional languages, where you might know them as streams or sequences. Now they've come to ECMAScript.
Understanding how generators work in practice requires a bit of explanation. To start, we define a simple collection of names. Now say that we want a function to return each of the names, one at a time per function call, until none are left:
At first, the above function-returning-a-function sleight-of-hand might
seem strange. It's necessary because the
needs to track its state across multiple function calls. In a language
like C, we could store state in a static variable inside the
getName function, but like its cousins Java and C#,
ECMAScript doesn't support static variables in a function. In this case we
use a closure, so that the function literal holds on to the "current"
variable after it returns, and uses that for its state.
The key thing to understand is that rather than handing back a finite sequence of values all at once (a la returning the array), this function hands each element back one at a time, until no more elements remain.
But what if you never ran out of elements to return?
Infinite streams in functional programming
It might seem like the previous code example is not much improvement over using an iterator across the names array. After all, that's what iterators do: provide individual element access across the contents of a collection. The important change comes when the original array is no longer visible, and isn't even an array anymore:
Technically, what you see is still an iterator, but its implementation looks wildly different from the iterators from patterns books; there's no collection here, just a set of hard-coded values.
In essence, it's an iterator without an associated collection, which highlights something important: that the source of the values being produced by our function is now deeply encapsulated away from the caller. This in turn creates an even more interesting idea: that the caller could be unaware that there is no collection to begin with, and that the values being produced are unending. This is what some languages call an infinite stream.
The Fibonacci sequence (the "Hello World" equivalent for every functional language on the planet) is one such infinite stream:
An infinite stream is one that will never run out of values to return. In this case, there is no logical end to the Fibonacci series.
While it might seem strange at first, the infinite stream concept is at the heart of some other interesting ECMAScript-based technology, such as reactive programming. Consider what happens if we think about user events (like mouse moves, button clicks, and key-presses) as infinite streams, which are then consumed by functions that pull each event off the stream and handle it.
The amount of code required to build an infinite stream is cumbersome, so ECMAScript 6 defines a new syntax (and a new keyword) to make things more succinct. You can see it here:
Once again, the function will print each name in order. When it runs out of
names it will print "undefined" ad infinitum. Syntactically, the
yield keyword looks like a return, but in fact, it's a
"return but remember where I was inside this function, so that the next
time it's called, we pick up execution where we left off." That's
obviously a bit more complicated than the traditional return.
Using the generator is a bit different from the first example: we've
captured the return of the
getName function, then used that
object like an iterator. This is a deliberate design decision in
ECMAScript 6. Technically, a generator function returns a
Generator object, which is used to obtain the individual
values from the generator function. The new syntax is designed to emulate
iterators as closely as possible.
Speaking of iterators, there's one last syntax change you need to know about.
The for-of keyword
for loop gets a new look in ECMAScript 6, due to
the addition of a secondary keyword:
of. In many ways, the
new syntax is not much different from
for-in, but it supports
things like generator functions.
Going back to the Fibonacci sequence, here's what happens if you add a
for-of keyword to the function:
There's a subtle difference between
for-in, but for the most part you can use
as a drop-in replacement for the older syntax. It just adds the ability to
use generators implicitly—like we did with
in the infinite streams example.
By now you've noticed that ECMAScript 6 definitely isn't a simple errata release. Many of the features I've introduced here stem from functional programming concepts, but don't let that fool you: ECMAScript 6 is far from a functional language. Adopting certain functional features can make writing ECMAScript code easier, but you don't need to know about monads, monoids, and category theory to do it. For the most part, the prevailing attitude seems to be: If it works for you, use it; if not, there are lots of other options.
So if you've never done any functional programming, don't stress—ECMAScript 6 invites you to dip your toes in the water, but you're definitely not going to be tossed into the deep end of the pool.
In any case, the next article in this series returns us to dry ground, with a guide to the new class-based syntax and object enhancements in ECMAScript 6.
- The ECMAScript 6 tools and platforms compatibility page
- New features in ECMAScript 6
- Node.js: ECMAScript 6 (ES6) and beyond
- IBM SDK for Node.js
- developerWorks Web development
- IBM Code: Node.js journeys