Please support this book: buy it (PDF, EPUB, MOBI) or donate

What you need to know about this book

This book is about ECMAScript 6 (whose official name is ECMAScript 2015), a new version of JavaScript.

Audience: JavaScript programmers

In order to understand this book, you should already know JavaScript. If you don’t: my other book “Speaking JavaScript” is free online and teaches programmers all of JavaScript (up to and including ECMAScript 5).

Why should I read this book?

  • You decide how deep to go: This book covers ECMAScript 6 in depth, but is structured so that you can also quickly get an overview if you want to.
  • Not just “what”, also “why”: This book not only tells you how ES6 works, it also tells you why it works the way it does.
  • Thoroughly researched: In order to make sense of ES6, I have consulted many sources:
    • The language specification (to which you’ll occasionally find pointers in this book)
    • The es-discuss mailing list
    • The TC39 meeting notes
    • Scientific papers
    • Documentation on features in other languages that inspired ES6 features
    • And more

How to read this book

This book covers ES6 with three levels of detail:

  • Quick start: Begin with the chapter “Core ES6 features”. Additionally, almost every chapter starts with a section giving an overview of what’s in the chapter. The last chapter collects all of these overview sections in a single location.
  • Solid foundation: Each chapter always starts with the essentials and then increasingly goes into details. The headings should give you a good idea of when to stop reading, but I also occasionally give tips in sidebars w.r.t. how important it is to know something.
  • In-depth knowledge: Read all of a chapter, including the in-depth parts. Other things to know:

  • Recommendations: I occasionally recommend simple rules. Those are meant as guidelines, to keep you safe without you having to know (or remember) all of the details. I tend to favor mainstream over elegance, because most code doesn’t exist in a vacuum. However, I’ll always give you enough information so that you can make up your own mind.

  • Forum: The “Exploring ES6” homepage links to a forum where you can discuss questions and ideas related to this book.
  • Errata (typos, errors, etc.): On the “Exploring ES6” homepage, there are links to a form for submitting errata and to a list with submitted errata.

Sources of this book

I started writing this book long before there were implementations of ES6 features, which required quite a bit of research. Essential sources were:

Glossary

Strict mode versus sloppy mode

ECMAScript 5 introduced language modes: Strict mode makes JavaScript a cleaner language by changing its semantics, performing more checks and throwing more exceptions. Consult Sect. “Strict Mode” in “Speaking JavaScript” for more information. The legacy/default mode is called non-strict mode or sloppy mode.

Strict mode is switched on via the following line (which does nothing in ECMAScript versions before ES5):

  1. 'use strict';

If you put this line at the beginning of a file, all code in it is in strict mode. If you make this line the first line of a function, only that function is in strict mode.

Using a directive to switch on strict mode is not very user friendly and was one of the reasons why strict mode was not nearly as popular in ES5 as it should be. However, ES6 modules and classes are implicitly in strict mode. Given that most ES6 code will live in modules, strict mode becomes the de-facto default for ES6.

Protocol

The term protocol has various meanings in computing. In the context of programming languages and API design, I’m using it as follows:

A protocol defines interfaces (signatures for methods and/or functions) and rules for using them.

The idea is to specify how a service is to be performed. Then anyone can perform the service and anyone can request it and they are guaranteed to work together well.

Note that the definition given here is different from viewing a protocol as an interface (as, for example, Objective C does), because this definition includes rules.

Receiver (of a method call)

Given a method call obj.m(···), obj is the receiver of the method call and accessible via this inside the method.

Signature of a function (or a method)

The (type) signature of a function describes how the function is to be called, what its inputs and its output are. I’m using the syntax established by Microsoft TypeScript and Facebook Flow in this book. An example of a signature:

  1. parseInt(string : string, radix? : number) : number

You can see that parseInt() expects a string and a number and returns a number. If the type of a parameter is clear, I often omit the type annotation.

Internal slots

The ES6 language specification uses internal slots to store internal data. In the spec, internal slots are accessed as if they were properties whose names are in square brackets:

  1. O.[[GetPrototypeOf]]()

Two things differentiate them from properties:

  • They are not read via “get” operations and written via “set” operations.
  • They are only known to the spec and not accessible from JavaScript. For example: the link between an object and its prototype is the internal slot [[Prototype]]. The value of that slot cannot be read directly via JavaScript, but you can use Object.getPrototypeOf() to do so. How exactly internal slots are stored is left unspecified. Some may not even exist in actual JavaScript implementations.

Bindings and environments

The ECMAScript spec uses a data structure called environment to store the variables of a scope. An environment is basically a dictionary that maps variable names to values. A binding is an entry in an environment, storage space for a variable.

Destructive operations

Destructive operations (methods, functions) modify their parameters or their receivers. For example, push() modifies its receiver arr:

  1. > const arr = ['a', 'b'];
  2. > arr.push('c')
  3. 3
  4. > arr
  5. [ 'a', 'b', 'c' ]

In contrast, concat() creates a new Array and does not change its receiver arr:

  1. > const arr = ['a', 'b'];
  2. > arr.concat(['c'])
  3. [ 'a', 'b', 'c' ]
  4. > arr
  5. [ 'a', 'b' ]

Conventions

Documenting classes

The API of a class C is usually documented as follows:

  • C constructor
  • Static C methods
  • C.prototype methods

Capitalization

In English, I capitalize JavaScript terms as follows:

  • The names of primitive entities are not capitalized: a boolean value, a number value, a symbol, a string. One reason why I’m doing this is because TypeScript and Flow distinguish:
    • The type String: its members are objects, instances of String.
    • The type string: its members are primitive values, strings.
  • The data structure Map is capitalized. Rationale: distinguish from the Array method map().
  • The data structure Set is capitalized. Rationale: distinguish from the verb set.
  • Array and Promise are capitalized. Rationale: easy to confuse with English words.
  • Not capitalized (for now): object, generator, proxy.

Demo code on GitHub

Several repositories on GitHub contain code shown in this book:

Sidebars

Sidebars are boxes of text marked with icons. They complement the normal content.

Footnotes

Occasionally, I refer to (publicly available) external material via footnotes. Two sources are marked with a prefix in square brackets:

  • [Spec] refers to content in the HTML version of the ES6 spec.
  • [Speaking JS] refers to content in the HTML version of “Speaking JavaScript”.