The Road to ECMAScript 6
In 2007, JavaScript was at a crossroads. The popularity of Ajax was ushering in a new age of dynamic web applications, whereas JavaScript hadn’t changed since the third edition of ECMA-262 was published in 1999.
{23}————————————————
TC-39, the committee responsible for driving the ECMAScript development process, put together a large draft specification for ECMAScript 4. ECMAScript 4 was massive in scope, introducing both small and large changes to the language. Updated features included new syntax, modules, classes, classical inheritance, private object members, optional type annotations, and more.
The scope of the ECMAScript 4 changes caused a rift to form in TC-39: some members felt that the fourth edition was trying to accomplish too much. A group of leaders from Yahoo!, Google, and Microsoft created an alternate proposal for the next version of ECMAScript that the group initially called ECMAScript 3.1. The “3.1” designation was intended to show that this version was an incremental change to the existing standard.
ECMAScript 3.1 introduced very few syntax changes; instead, it focused on property attributes, native JSON support, and adding methods to already existing objects. Although an early attempt was made to reconcile ECMAScript 3.1 and ECMAScript 4, the effort ultimately failed because the two camps had difficulty resolving the very different perspectives on how the language should grow.
In 2008, Brendan Eich, the creator of JavaScript, announced that TC-39 would focus its efforts on standardizing ECMAScript 3.1. It would table the major syntax and feature changes of ECMAScript 4 until after the next version of ECMAScript was standardized, and all members of the committee would work to bring the best pieces of ECMAScript 3.1 and 4 together after that point into an effort initially nicknamed ECMAScript Harmony.
ECMAScript 3.1 was eventually standardized as the fifth edition of ECMA-262, also described as ECMAScript 5. The committee never released an ECMAScript 4 standard to avoid confusion with the nowdefunct effort of the same name. Work then began on ECMAScript Harmony, with ECMAScript 6 being the first standard released in this new “harmonious” spirit.
ECMAScript 6 reached feature complete status in 2015 and was formally dubbed “ECMAScript 2015.” (But this text still refers to it as ECMAScript 6, the name most familiar to developers.) The features vary widely from completely new objects and patterns to syntax changes and new methods on existing objects. The exciting aspect of ECMAScript 6 is that all of its changes are geared toward solving problems that developers actually face.
About This Book
A good understanding of ECMAScript 6 features is critical for all JavaScript developers going forward. The language features introduced in ECMA-Script 6 represent the foundation upon which JavaScript applications will be built for the foreseeable future. That’s where this book comes in. My hope is that you’ll read this book to learn about ECMAScript 6 features so you’ll be ready to start using them as soon as you need to.
{24}————————————————
Browser and Node.js Compatibility
Many JavaScript environments, such as web browsers and Node.js, are actively working on implementing ECMAScript 6. This book doesn’t attempt to address the inconsistencies between implementations; instead, it focuses on what the specification defines as the correct behavior. As such, it’s possible that your JavaScript environment may not conform to the behavior described in this book.
Who This Book Is For
This book is intended as a guide for those who are already familiar with JavaScript and ECMAScript 5. Although a deep understanding of the language isn’t necessary to use this book, it will help you understand the differences between ECMAScript 5 and 6. In particular, this book is aimed at intermediate-to-advanced JavaScript developers programming for a browser or Node.js environment who want to learn about the latest developments in the language.
This book is not for beginners who have never written JavaScript. You’ll need to have a good basic understanding of the language to use this book.
Overview
Each chapter and appendix in this book covers a different aspect of ECMAScript 6. Many chapters start by discussing problems that ECMA-Script 6 changes were made to solve to give you a broader context for those changes. All chapters include code examples to help you learn new syntax and concepts.
- • Chapter 1: Block Bindings talks about let and const, the block-level replacement for var.
- • Chapter 2: Strings and Regular Expressions covers additional functionality for string manipulation and inspection as well as the introduction of template strings.
- • Chapter 3: Functions discusses the various changes to functions, including the arrow function form, default parameters, rest parameters, and a few other features.
- • Chapter 4: Expanded Object Functionality explains the changes to how objects are created, modified, and used. Topics include changes to object literal syntax and new reflection methods.
- • Chapter 5: Destructuring for Easier Data Access introduces object and array destructuring, which allow you to decompose objects and arrays using a concise syntax.
- • Chapter 6: Symbols and Symbol Properties introduces the concept of symbols, a new way to define properties. Symbols are a new primitive type that you can use to obscure (but not hide) object properties and methods.
{25}————————————————
- • Chapter 7: Sets and Maps details the new collection types of Set, WeakSet, Map, and WeakMap. These types expand on the usefulness of arrays by adding semantics, de-duping, and memory management designed specifically for JavaScript.
- • Chapter 8: Iterators and Generators discusses the addition of iterators and generators to the language. These features allow you to work with collections of data in powerful ways that were not possible in previous versions of JavaScript.
- • Chapter 9: Introducing JavaScript Classes introduces the first formal concept of classes in JavaScript. Often a point of confusion for those coming from other languages, the addition of class syntax in JavaScript makes the language more approachable to others and more concise for enthusiasts.
- • Chapter 10: Improved Array Capabilities details the changes to native arrays and the useful new ways you can use them in JavaScript.
- • Chapter 11: Promises and Asynchronous Programming introduces promises as a new part of the language. Promises were a grassroots effort that eventually took off and gained popularity due to extensive library support. ECMAScript 6 formalizes promises and makes them available by default.
- • Chapter 12: Proxies and the Reflection API introduces the formalized reflection API for JavaScript and the new proxy object that allows you to intercept every operation performed on an object. Proxies give developers unprecedented control over objects and, as such, unlimited possibilities for defining new interaction patterns.
- • Chapter 13: Encapsulating Code with Modules details the official module format for JavaScript. The intent is that these modules can replace the numerous ad hoc module definition formats that have appeared over the years.
- • Appendix A: Minor Changes in ECMAScript 6 covers other changes implemented in ECMAScript 6 that you’ll use less frequently or that didn’t quite fit into the broader major topics covered in each chapter.
- • Appendix B: Understanding ECMAScript 7 (2016) describes the three additions to the standard that were implemented in ECMAScript 7, which didn’t impact JavaScript nearly as much as ECMAScript 6.
Conventions Used
The following typographical conventions are used in this book:
- • Italics are used for new terms and filenames.
- • Constant width indicates a code term within the text.
{26}————————————————
Additionally, longer code examples are contained in constant width code blocks, such as the following:
function doSomething() {
// empty
}
Within a code block, comments to the right of a console.log() statement indicate the output you’ll see in the browser or Node.js console when the code is executed; for example:
console.log("Hi"); // "Hi"
If a line of code in a code block throws an error, it is also indicated to the right of the code:
doSomething(); // throws an error
Help and Support
If you have questions as you read this book, please send a message to my mailing list at http://groups.google.com/group/zakasbooks.
{27}————————————————
{28}————————————————
1
Block Bindings
Traditionally, the way variable declarations work has been one tricky part of programming in JavaScript. In most C-based languages, variables (more formally known as bindings, as a name is bound to a value inside a scope) are created at the spot where the declaration occurs. In JavaScript, however, this is not the case. Where your variables are actually created depends on how you declare them, and ECMAScript 6 offers options to make controlling scope easier. This chapter demonstrates why classic var declarations can be confusing, introduces block-level bindings in ECMAScript 6, and then offers some best practices for using them.
{29}————————————————
var Declarations and Hoisting
Variable declarations using var are treated as if they’re at the top of the function (or in the global scope, if declared outside of a function) regardless of where the actual declaration occurs; this is called hoisting. For a demonstration of what hoisting does, consider the following function definition:
function getValue(condition) {
if (condition) {
var value = "blue";
// other code
return value;
} else {
// value exists here with a value of undefined
return null;
}
// value exists here with a value of undefined
}
If you are unfamiliar with JavaScript, you might expect the variable value to be created only if condition evaluates to true. In fact, the variable value is created regardless. Behind the scenes, the JavaScript engine changes the getValue function to look like this:
function getValue(condition) {
var value;
if (condition) {
value = "blue";
// other code
return value;
} else {
return null;
}
}
The declaration of value is hoisted to the top, and the initialization remains in the same spot. That means the variable value is still accessible from within the else clause. If accessed from the else clause, the variable would just have a value of undefined because it hasn’t been initialized in the else block.
{30}————————————————
It often takes new JavaScript developers some time to get used to declaration hoisting, and misunderstanding this unique behavior can end up causing bugs. For this reason, ECMAScript 6 introduces block-level scoping options to give developers more control over a variable’s life cycle.