Understanding ECMAScript 6: The Definitive Guide for JavaScript Developers
4/5
()
About this ebook
You’ll learn:
–How ECMAScript 6 class syntax relates to more familiar JavaScript concepts
–What makes iterators and generators useful
–How arrow functions differ from regular functions
–Ways to store data with sets, maps, and more
–The power of inheritance
–How to improve asynchronous programming with promises
–How modules change the way you organize code
Whether you’re a web developer or a Node.js developer, you’ll find Understanding ECMAScript 6 indispensable on your journey from ECMAScript 5 to ECMAScript 6.
Nicholas C. Zakas
Nicholas C. Zakas is a front-end consultant, author, and speaker. He worked at Yahoo! for almost five years, where he was front-end tech lead for the Yahoo! homepage and a contributor to the YUI library. He is the author of Professional JavaScript for Web Developers (Wrox, 2012), Professional Ajax (Wrox, 2007), and High Performance JavaScript(O’Reilly, 2010). Nicholas is a strong advocate for development best practices including progressive enhancement, accessibility, performance, scalability, and maintainability. He blogs regularly at http://www.nczonline.net/ and can be found on Twitter via @slicknet.
Read more from Nicholas C. Zakas
Understanding JavaScript Promises Rating: 0 out of 5 stars0 ratingsThe Principles of Object-Oriented JavaScript Rating: 4 out of 5 stars4/5Professional JavaScript for Web Developers Rating: 0 out of 5 stars0 ratings
Related to Understanding ECMAScript 6
Related ebooks
The Definitive JavaScript Handbook: From Fundamentals to Cutting‑Edge Best Practices Rating: 0 out of 5 stars0 ratingsJavascript Mastery: In-Depth Techniques and Strategies for Advanced Development Rating: 0 out of 5 stars0 ratingsThe Ultimate Guide to Mastering JavaScript: A Beginner's Journey Rating: 0 out of 5 stars0 ratingsMastering the Craft of JavaScript Programming: Unraveling the Secrets of Expert-Level Programming Rating: 0 out of 5 stars0 ratingsJavaScript OOP Step by Step: A Practical Guide with Examples Rating: 0 out of 5 stars0 ratingsLearning JavaScript Fast: Build Web Interactivity Using Powerful JavaScript Tools Rating: 0 out of 5 stars0 ratings120 Advanced JavaScript Interview Questions Rating: 0 out of 5 stars0 ratingsJavaScript Made Easy: A Practical Guide with Examples Rating: 0 out of 5 stars0 ratingsClean Code in JavaScript: Develop reliable, maintainable, and robust JavaScript Rating: 5 out of 5 stars5/5JavaScript: Best Practice Rating: 0 out of 5 stars0 ratingsJavaScript Fundamentals Made Easy: A Practical Guide with Examples Rating: 0 out of 5 stars0 ratingsJavaScript Data Structures Explained: A Practical Guide with Examples Rating: 0 out of 5 stars0 ratingsMastering JavaScript Secure Web Development+: Unlock the Secrets of Expert-Level Skills Rating: 0 out of 5 stars0 ratingsMicrosoft AJAX Library Essentials: Client-side ASP.NET AJAX 1.0 Explained Rating: 0 out of 5 stars0 ratingsMastering JavaScript Rating: 4 out of 5 stars4/5Mastering Node.js Web Development: Go on a comprehensive journey from the fundamentals to advanced web development with Node.js Rating: 0 out of 5 stars0 ratingsCoding with JavaScript For Dummies Rating: 0 out of 5 stars0 ratingsJavaScript: Novice to Ninja Rating: 2 out of 5 stars2/5Node.js for Beginners: A comprehensive guide to building efficient, full-featured web applications with Node.js Rating: 0 out of 5 stars0 ratingsJavaScript Functional Programming Made Simple: A Practical Guide with Examples Rating: 0 out of 5 stars0 ratingsThe Joy of JavaScript With a Side of Vue.js Rating: 0 out of 5 stars0 ratingsJavaScript Unleashed: Scripting the Web: A Comprehensive Guide to JavaScript Programming Rating: 0 out of 5 stars0 ratingsJavaScript Design Patterns: Deliver fast and efficient production-grade JavaScript applications at scale Rating: 0 out of 5 stars0 ratingsModern JavaScript: Coding for Today and Tomorrow Rating: 0 out of 5 stars0 ratingsJavaScript for Beginners Rating: 5 out of 5 stars5/5Building Scalable Web Apps with Node.js and Express Rating: 0 out of 5 stars0 ratingsJasmine JavaScript Testing - Second Edition Rating: 0 out of 5 stars0 ratingsNode.js, JavaScript, API: Interview Questions and Answers Rating: 5 out of 5 stars5/5
Programming For You
Excel 101: A Beginner's & Intermediate's Guide for Mastering the Quintessence of Microsoft Excel (2010-2019 & 365) in no time! Rating: 0 out of 5 stars0 ratingsCoding All-in-One For Dummies Rating: 0 out of 5 stars0 ratingsSQL QuickStart Guide: The Simplified Beginner's Guide to Managing, Analyzing, and Manipulating Data With SQL Rating: 4 out of 5 stars4/5Spies, Lies, and Algorithms: The History and Future of American Intelligence Rating: 4 out of 5 stars4/5SQL All-in-One For Dummies Rating: 3 out of 5 stars3/5Coding All-in-One For Dummies Rating: 4 out of 5 stars4/5Python: For Beginners A Crash Course Guide To Learn Python in 1 Week Rating: 4 out of 5 stars4/5Learn to Code. Get a Job. The Ultimate Guide to Learning and Getting Hired as a Developer. Rating: 5 out of 5 stars5/5Python Programming : How to Code Python Fast In Just 24 Hours With 7 Simple Steps Rating: 4 out of 5 stars4/5Learn PowerShell in a Month of Lunches, Fourth Edition: Covers Windows, Linux, and macOS Rating: 5 out of 5 stars5/5JavaScript All-in-One For Dummies Rating: 5 out of 5 stars5/5HTML in 30 Pages Rating: 5 out of 5 stars5/5Coding with JavaScript For Dummies Rating: 0 out of 5 stars0 ratingsPYTHON PROGRAMMING Rating: 4 out of 5 stars4/5Linux: Learn in 24 Hours Rating: 5 out of 5 stars5/5Excel : The Ultimate Comprehensive Step-By-Step Guide to the Basics of Excel Programming: 1 Rating: 5 out of 5 stars5/5Python for Data Science For Dummies Rating: 0 out of 5 stars0 ratingsPython: Learn Python in 24 Hours Rating: 4 out of 5 stars4/5Microsoft Azure For Dummies Rating: 0 out of 5 stars0 ratingsProblem Solving in C and Python: Programming Exercises and Solutions, Part 1 Rating: 5 out of 5 stars5/5Learn SQL in 24 Hours Rating: 5 out of 5 stars5/5Python Data Structures and Algorithms Rating: 5 out of 5 stars5/5
Reviews for Understanding ECMAScript 6
5 ratings0 reviews
Book preview
Understanding ECMAScript 6 - Nicholas C. Zakas
BRIEF CONTENTS
Foreword by Dan Abramov
Acknowledgments
Introduction
Chapter 1: Block Bindings
Chapter 2: Strings and Regular Expressions
Chapter 3: Functions
Chapter 4: Expanded Object Functionality
Chapter 5: Destructuring for Easier Data Access
Chapter 6: Symbols and Symbol Properties
Chapter 7: Sets and Maps
Chapter 8: Iterators and Generators
Chapter 9: Introducing JavaScript Classes
Chapter 10: Improved Array Capabilities
Chapter 11: Promises and Asynchronous Programming
Chapter 12: Proxies and the Reflection API
Chapter 13: Encapsulating Code with Modules
Appendix A: Minor Changes in ECMAScript 6
Appendix B: Understanding ECMAScript 7 (2016)
Index
CONTENTS IN DETAIL
FOREWORD by Dan Abramov
ACKNOWLEDGMENTS
INTRODUCTION
The Road to ECMAScript 6
About This Book
Browser and Node.js Compatibility
Who This Book Is For
Overview
Conventions Used
Help and Support
1
BLOCK BINDINGS
var Declarations and Hoisting
Block-Level Declarations
let Declarations
No Redeclaration
const Declarations
The Temporal Dead Zone
Block Bindings in Loops
Functions in Loops
let Declarations in Loops
const Declarations in Loops
Global Block Bindings
Emerging Best Practices for Block Bindings
Summary
2
STRINGS AND REGULAR EXPRESSIONS
Better Unicode Support
UTF-16 Code Points
The codePointAt() Method
The String.fromCodePoint() Method
The normalize() Method
The Regular Expression u Flag
Other String Changes
Methods for Identifying Substrings
The repeat() Method
Other Regular Expression Changes
The Regular Expression y Flag
Duplicating Regular Expressions
The flags Property
Template Literals
Basic Syntax
Multiline Strings
Making Substitutions
Tagged Templates
Summary
3
FUNCTIONS
Functions with Default Parameter Values
Simulating Default Parameter Values in ECMAScript 5
Default Parameter Values in ECMAScript 6
How Default Parameter Values Affect the arguments Object
Default Parameter Expressions
Default Parameter TDZ
Working with Unnamed Parameters
Unnamed Parameters in ECMAScript 5
Rest Parameters
Increased Capabilities of the Function Constructor
The Spread Operator
The name Property
Choosing Appropriate Names
Special Cases of the name Property
Clarifying the Dual Purpose of Functions
Determining How a Function Was Called in ECMAScript 5
The new.target Metaproperty
Block-Level Functions
Deciding When to Use Block-Level Functions
Block-Level Functions in Non-Strict Mode
Arrow Functions
Arrow Function Syntax
Creating Immediately Invoked Function Expressions
No this Binding
Arrow Functions and Arrays
No arguments Binding
Identifying Arrow Functions
Tail Call Optimization
How Tail Calls Are Different in ECMAScript 6
How to Harness Tail Call Optimization
Summary
4
EXPANDED OBJECT FUNCTIONALITY
Object Categories
Object Literal Syntax Extensions
Property Initializer Shorthand
Concise Methods
Computed Property Names
New Methods
The Object.is() Method
The Object.assign() Method
Duplicate Object Literal Properties
Own Property Enumeration Order
Enhancements for Prototypes
Changing an Object’s Prototype
Easy Prototype Access with Super References
A Formal Method Definition
Summary
5
DESTRUCTURING FOR EASIER DATA ACCESS
Why Is Destructuring Useful?
Object Destructuring
Destructuring Assignment
Default Values
Assigning to Different Local Variable Names
Nested Object Destructuring
Array Destructuring
Destructuring Assignment
Default Values
Nested Array Destructuring
Rest Items
Mixed Destructuring
Destructured Parameters
Destructured Parameters Are Required
Default Values for Destructured Parameters
Summary
6
SYMBOLS AND SYMBOL PROPERTIES
Creating Symbols
Using Symbols
Sharing Symbols
Symbol Coercion
Retrieving Symbol Properties
Exposing Internal Operations with Well-Known Symbols
The Symbol.hasInstance Method
The Symbol.isConcatSpreadable Property
The Symbol.match, Symbol.replace, Symbol.search, and Symbol.split Properties
The Symbol.toPrimitive Method
The Symbol.toStringTag Property
The Symbol.unscopables Property
Summary
7
SETS AND MAPS
Sets and Maps in ECMAScript 5
Problems with Workarounds
Sets in ECMAScript 6
Creating Sets and Adding Items
Removing Items
The forEach() Method for Sets
Converting a Set to an Array
Weak Sets
Maps in ECMAScript 6
Map Methods
Map Initialization
The forEach() Method for Maps
Weak Maps
Summary
8
ITERATORS AND GENERATORS
The Loop Problem
What Are Iterators?
What Are Generators?
Generator Function Expressions
Generator Object Methods
Iterables and for-of Loops
Accessing the Default Iterator
Creating Iterables
Built-In Iterators
Collection Iterators
String Iterators
NodeList Iterators
The Spread Operator and Nonarray Iterables
Advanced Iterator Functionality
Passing Arguments to Iterators
Throwing Errors in Iterators
Generator Return Statements
Delegating Generators
Asynchronous Task Running
A Simple Task Runner
Task Running with Data
An Asynchronous Task Runner
Summary
9
INTRODUCING JAVASCRIPT CLASSES
Class-Like Structures in ECMAScript 5
Class Declarations
A Basic Class Declaration
Why Use the Class Syntax?
Class Expressions
A Basic Class Expression
Named Class Expressions
Classes as First-Class Citizens
Accessor Properties
Computed Member Names
Generator Methods
Static Members
Inheritance with Derived Classes
Shadowing Class Methods
Inherited Static Members
Derived Classes from Expressions
Inheriting from Built-Ins
The Symbol.species Property
Using new.target in Class Constructors
Summary
10
IMPROVED ARRAY CAPABILITIES
Creating Arrays
The Array.of() Method
The Array.from() Method
New Methods on All Arrays
The find() and findIndex() Methods
The fill() Method
The copyWithin() Method
Typed Arrays
Numeric Data Types
Array Buffers
Manipulating Array Buffers with Views
Similarities Between Typed and Regular Arrays
Common Methods
The Same Iterators
The of() and from() Methods
Differences Between Typed and Regular Arrays
Behavioral Differences
Missing Methods
Additional Methods
Summary
11
PROMISES AND ASYNCHRONOUS PROGRAMMING
Asynchronous Programming Background
The Event Model
The Callback Pattern
Promise Basics
The Promise Life Cycle
Creating Unsettled Promises
Creating Settled Promises
Executor Errors
Global Promise Rejection Handling
Node.js Rejection Handling
Browser Rejection Handling
Chaining Promises
Catching Errors
Returning Values in Promise Chains
Returning Promises in Promise Chains
Responding to Multiple Promises
The Promise.all() Method
The Promise.race() Method
Inheriting from Promises
Promise-Based Asynchronous Task Running
Summary
12
PROXIES AND THE REFLECTION API
The Array Problem
Introducing Proxies and Reflection
Creating a Simple Proxy
Validating Properties Using the set Trap
Object Shape Validation Using the get Trap
Hiding Property Existence Using the has Trap
Preventing Property Deletion with the deleteProperty Trap
Prototype Proxy Traps
How Prototype Proxy Traps Work
Why Two Sets of Methods?
Object Extensibility Traps
Two Basic Examples
Duplicate Extensibility Methods
Property Descriptor Traps
Blocking Object.defineProperty()
Descriptor Object Restrictions
Duplicate Descriptor Methods
The ownKeys Trap
Function Proxies with the apply and construct Traps
Validating Function Parameters
Calling Constructors Without new
Overriding Abstract Base Class Constructors
Callable Class Constructors
Revocable Proxies
Solving the Array Problem
Detecting Array Indexes
Increasing length When Adding New Elements
Deleting Elements When Reducing length
Implementing the MyArray Class
Using a Proxy as a Prototype
Using the get Trap on a Prototype
Using the set Trap on a Prototype
Using the has Trap on a Prototype
Proxies as Prototypes on Classes
Summary
13
ENCAPSULATING CODE WITH MODULES
What Are Modules?
Basic Exporting
Basic Importing
Importing a Single Binding
Importing Multiple Bindings
Importing an Entire Module
A Subtle Quirk of Imported Bindings
Renaming Exports and Imports
Default Values in Modules
Exporting Default Values
Importing Default Values
Re-exporting a Binding
Importing Without Bindings
Loading Modules
Using Modules in Web Browsers
Browser Module Specifier Resolution
Summary
A
MINOR CHANGES IN ECMASCRIPT 6
Working with Integers
Identifying Integers
Safe Integers
New Math Methods
Unicode Identifiers
Formalizing the __proto__ Property
B
UNDERSTANDING ECMASCRIPT 7 (2016)
The Exponentiation Operator
Order of Operations
Operand Restriction
The Array.prototype.includes() Method
How to Use Array.prototype.includes()
Value Comparison
A Change to Function-Scoped Strict Mode
INDEX
FOREWORD
ECMAScript 6 has taken the world by storm. It came long after people stopped waiting for it, and then it spread faster than most people could learn it. Everybody has a different story about it. Here is mine.
In 2013, I worked at a startup that pivoted from iOS to the web. It was before I co-created Redux or participated in the JavaScript open source community. At the time, I was struggling to learn web development, and I was terrified. My team had to build a web version of our product from scratch in just a few months. In JavaScript.
At first I scoffed at the idea of writing something large in JavaScript. But a new team member persuaded me that JavaScript was not a toy language. I agreed to give it a try. I set my prejudices aside, opened MDN and StackOverflow, and learned JavaScript in depth for the first time. The simplicity I discovered enchanted me. My colleague also taught me how to use tools such as a linter and a bundler. In a few weeks, I woke up and realized that I enjoyed writing JavaScript.
But no language is perfect. I missed the frequent updates that I’d come to expect after working with other languages. The only substantial update to JavaScript in a decade, ECMAScript 5, was a mere cleanup that nevertheless took years for browsers to fully support. At the time, the upcoming ECMAScript 6 (ES6) specification, codenamed Harmony, was far from finished and seemed like a distant future. Maybe in 10 years I’ll get to write some ES6 code,
I thought.
There were some experimental transpilers
like Google Traceur that translated code from ES6 into ES5. Most of them were very limited or hard to plug into an existing JavaScript build pipeline. But then a new transpiler called 6to5 came along and changed everything. It was easy to install, integrated well with the existing tools, and produced readable code. It spread like wildfire. Now called Babel, 6to5 brought ES6 features to a mainstream audience even before the specification was finalized. In a matter of months, ES6 was everywhere.
ES6 has divided the community for a number of reasons. As this book goes to press, it is still not fully implemented in many major browsers. Having a build step can be intimidating when you’re just learning the language. Some libraries have documentation and examples in ES6, and you might wonder if it is possible to use those libraries in ES5 at all. This contributes to the confusion. Many people didn’t expect any new features in the language because it had almost never changed before. Others anxiously awaited the new features’ arrival and used all of them together—in some cases beyond what was necessary.
Just as I was becoming proficient with JavaScript, I felt that somebody pulled the rug from under my feet, and now I had to learn a new language. I felt bad about this for a few months. Finally, on Christmas Eve, I started reading a draft of this book. I couldn’t put it down. Next thing I knew, it was 3 AM, everybody at the party was asleep, and I understood ES6!
Nicholas is an incredibly gifted teacher. He conveys deep details in a straightforward way so they don’t go over your head. Apart from this book, he is also known for creating ESLint, a JavaScript code analyzer that has been downloaded millions of times.
Nicholas knows JavaScript like very few people do. Don’t miss the chance to soak up some of his knowledge. Read this book, and you, too, will become confident in your understanding of ES6.
Dan Abramov
React core team member and creator of Redux
ACKNOWLEDGMENTS
Thanks to Jennifer Griffith-Delgado, Alison Law, and everyone at No Starch Press for their support and help with this book. Their understanding and patience as my productivity slowed to a crawl during my extended illness is something I will never forget.
I’m grateful for the watchful eye of Juriy Zaytsev as technical editor and to Dr. Axel Rauschmayer for his feedback and several conversations that helped to clarify some of the concepts discussed in this book.
Thanks to everyone who submitted fixes to the version of this book that is hosted on GitHub: 404, alexyans, Ahmad Ali, Raj Anand, Arjunkumar, Pahlevi Fikri Auliya, Mohsen Azimi, Peter Bakondy, Sarbbottam Bandyopadhyay, blacktail, Philip Borisov, Nick Bottomley, Ethan Brown, Jeremy Caney, Jake Champion, David Chang, Carlo Costantini, Aaron Dandy, Niels Dequeker, Aleksandar Djindjic, Joe Eames, Lewis Ellis, Ronen Elster, Jamund Ferguson, Steven Foote, Ross Gerbasi, Shaun Hickson, Darren Huskie, jakub-g, kavun, Navaneeth Kesavan, Dan Kielp, Roy Ling, Roman Lo, Lonniebiz, Kevin Lozandier, Josh Lubaway, Mallory, Jakub Narębski, Robin Pokorný, Kyle Pollock, Francesco Pongiluppi, Nikolas Poniros, AbdulFattah Popoola, Ben Regenspan, Adam Richeimer, robertd, Marián Rusnák, Paul Salaets, Shidhin, ShMcK, Kyle Simpson, Igor Skuhar, Yang Su, Erik Sundahl, Dmitri Suvorov, Kevin Sweeney, Prayag Verma, Rick Waldron, Kale Worsley, Juriy Zaytsev, and Eugene Zubarev.
Also, thanks to Casey Visco, who supported this book on Patreon.
INTRODUCTION
The JavaScript core language features are defined in the ECMA-262 standard. The language defined in this standard is called ECMAScript. What you know as JavaScript in browsers and in Node.js is actually a superset of ECMAScript. Browsers and Node.js add more functionality through additional objects and methods, but the core of JavaScript remains as defined in ECMAScript. The ongoing development of ECMA-262 is vital to the success of JavaScript as a whole, and this book covers the changes brought about by the most recent major update to the language: ECMAScript 6.
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. 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 now-defunct 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 ECMAScript 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.
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 ECMAScript 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.
• 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.
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.
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.
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.
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.
Block-Level Declarations
Block-level declarations declare bindings that are inaccessible outside a given block scope. Block scopes, also called lexical scopes, are created in the following places:
• Inside a function
• Inside a block (indicated by the { and } characters)
Block scoping is how many C-based languages work, and the introduction of block-level declarations in ECMAScript 6 is intended to provide that same flexibility (and uniformity) to JavaScript.
let Declarations
The let declaration syntax is the same as the syntax for var. You can basically replace var with let to declare a variable but limit the variable’s scope to only the current code block (there are a few other subtle differences, which are discussed in "The Temporal Dead Zone" on page 6). Because let declarations are not hoisted to the top of the enclosing block, it’s best to place let declarations first in the block so they’re available to the entire block. Here’s an example:
function getValue(condition) {
if (condition) {
let value = blue
;
// other code
return value;
} else {
// value doesn't exist here
return null;
}
// value doesn't exist here
}
This version of the getValue function behaves more similarly to how you’d expect it to in other C-based languages. Because the variable value is declared using let instead of var, the declaration isn’t hoisted to the top of the function definition, and the variable value is no longer accessible once execution flows out of the if block. If condition evaluates to false, then value is never declared or initialized.
No Redeclaration
If an identifier has already been defined in a scope, using the identifier in a let declaration inside that scope causes an error to be thrown. For example:
var count = 30;
// throws an error
let count = 40;
In this example, count is declared twice: once with var and once with let. Because let will not redefine an identifier that already exists in the same scope, the let declaration will throw an error. Conversely, no error is thrown if a let declaration creates a new variable with the same name as a variable in its containing scope, as demonstrated in the following code:
var count = 30;
if (condition) {
// doesn't throw an error
let count = 40;
// more code
}
This let declaration doesn’t throw an error because it creates a new variable called count within the if statement instead of creating count in the surrounding block. Inside the if block, this new variable shadows the global count, preventing access to it until execution exits the block.
const Declarations
You can also define bindings in ECMAScript 6 with the const declaration syntax. Bindings declared using const are considered constants, meaning their values cannot be changed once set. For this reason, every const binding must be initialized on declaration, as shown in this example:
// valid constant
const maxItems = 30;
// syntax error: missing initialization
const name;
The maxItems binding is initialized, so its const declaration will work without a problem. However, the name binding would cause a syntax error if you tried to run the program containing this code because name is not initialized.
Constants vs. let Declarations
Constants, like let declarations, are block-level declarations. That means constants are no longer accessible once execution flows out of the block in which they were declared, and declarations are not hoisted, as demonstrated in this example:
if (condition) {
const maxItems = 5;
// more code
}
// maxItems isn't accessible here
In this code, the constant maxItems is declared within an if statement. After the statement finishes executing, maxItems is not accessible outside that block.
In another similarity to let, a const declaration throws an error when made with an identifier for an already defined variable in the same scope. It doesn’t matter whether that variable was declared using var (for global or function scope) or let (for block scope). For example, consider this code:
var message = Hello!
;
let age = 25;
// each of these throws an error
const message = Goodbye!
;
const age = 30;
The two const declarations would be valid alone, but given the previous var and let declarations in this case, they are syntax errors.
Despite those similarities, there is one significant difference between let and const. Attempting to assign a const to a previously defined constant will throw an error in both strict and non-strict modes:
const maxItems = 5;
// throws an error
maxItems = 6;
Much like constants in other languages, the maxItems variable can’t be assigned a new value later on. However, unlike constants in other languages, the value a constant