📄 Page
1
Ethan Brown Learning JavaScript JAVASCRIPT ESSENTIALS FOR MODERN APPLICATION DEVELOPMENT 3rd Edition
📄 Page
2
(This page has no text content)
📄 Page
3
Ethan Brown Learning JavaScript THIRD EDITION Boston Farnham Sebastopol TokyoBeijing
📄 Page
4
978-1-491-91491-5 [LSI] Learning JavaScript by Ethan Brown Copyright © 2016 Ethan Brown. All rights reserved. Printed in the United States of America. Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472. O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://safaribooksonline.com). For more information, contact our corporate/ institutional sales department: 800-998-9938 or corporate@oreilly.com. Editor: Meg Foley Production Editor: Kristen Brown Copyeditor: Rachel Monaghan Proofreader: Jasmine Kwityn Indexer: Judith McConville Interior Designer: David Futato Cover Designer: Karen Montgomery Illustrator: Rebecca Demarest October 2006: First Edition December 2008: Second Edition March 2016: Third Edition Revision History for the Third Edition 2016-02-12: First Release 2016-04-15: Second Release 2016-05-13: Third Release See http://oreilly.com/catalog/errata.csp?isbn=9781491914915 for release details. The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. Learning JavaScript, the cover image of a baby rhino, and related trade dress are trademarks of O’Reilly Media, Inc. While the publisher and the author have used good faith efforts to ensure that the information and instructions contained in this work are accurate, the publisher and the author disclaim all responsibility for errors or omissions, including without limitation responsibility for damages resulting from the use of or reliance on this work. Use of the information and instructions contained in this work is at your own risk. If any code samples or other technology this work contains or describes is subject to open source licenses or the intellectual property rights of others, it is your responsibility to ensure that your use thereof complies with such licenses and/or rights.
📄 Page
5
For Mark—a true friend, and fellow creator.
📄 Page
6
(This page has no text content)
📄 Page
7
Table of Contents Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv 1. Your First Application. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Where to Start 2 The Tools 2 A Comment on Comments 4 Getting Started 5 The JavaScript Console 7 jQuery 8 Drawing Graphics Primitive 9 Automating Repetitive Tasks 11 Handling User Input 12 Hello, World 13 2. JavaScript Development Tools. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Writing ES6 Today 15 ES6 Features 16 Installing Git 17 The Terminal 17 Your Project Root 18 Version Control: Git 18 Package Management: npm 21 Build Tools: Gulp and Grunt 23 Project Structure 24 The Transcompilers 25 Running Babel with Gulp 25 Linting 27 Conclusion 30 v
📄 Page
8
3. Literals, Variables, Constants, and Data Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 Variables and Constants 33 Variables or Constants: Which to Use? 35 Identifier Names 35 Literals 36 Primitive Types and Objects 37 Numbers 38 Strings 40 Escaping 40 Special Characters 41 Template Strings 42 Multiline Strings 43 Numbers as Strings 44 Booleans 44 Symbols 44 null and undefined 45 Objects 45 Number, String, and Boolean Objects 48 Arrays 48 Trailing Commas in Objects and Arrays 50 Dates 51 Regular Expressions 51 Maps and Sets 52 Data Type Conversion 52 Converting to Numbers 52 Converting to String 53 Converting to Boolean 53 Conclusion 54 4. Control Flow. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 A Control Flow Primer 55 while Loops 59 Block Statements 59 Whitespace 60 Helper Functions 61 if…else Statement 62 do…while Loop 63 for Loop 64 if Statement 65 Putting It All Together 66 Control Flow Statements in JavaScript 68 Control Flow Exceptions 68 vi | Table of Contents
📄 Page
9
Chaining if...else Statements 69 Metasyntax 69 Additional for Loop Patterns 71 switch Statements 72 for...in loop 75 for...of loop 75 Useful Control Flow Patterns 76 Using continue to Reduce Conditional Nesting 76 Using break or return to Avoid Unnecessary Computation 76 Using Value of Index After Loop Completion 77 Using Descending Indexes When Modifying Lists 77 Conclusion 78 5. Expressions and Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 Operators 81 Arithmetic Operators 81 Operator Precedence 83 Comparison Operators 85 Comparing Numbers 87 String Concatenation 88 Logical Operators 88 Truthy and Falsy Values 89 AND, OR, and NOT 89 Short-Circuit Evaluation 91 Logical Operators with Nonboolean Operands 91 Conditional Operator 92 Comma Operator 93 Grouping Operator 93 Bitwise Operators 93 typeof Operator 95 void Operator 96 Assignment Operators 96 Destructuring Assignment 97 Object and Array Operators 99 Expressions in Template Strings 99 Expressions and Control Flow Patterns 99 Converting if...else Statements to Conditional Expressions 100 Converting if Statements to Short-Circuited Logical OR Expressions 100 Conclusion 100 6. Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 Return Values 102 Table of Contents | vii
📄 Page
10
Calling Versus Referencing 102 Function Arguments 103 Do Arguments Make the Function? 105 Destructuring Arguments 106 Default Arguments 107 Functions as Properties of Objects 107 The this Keyword 108 Function Expressions and Anonymous Functions 110 Arrow Notation 111 call, apply, and bind 112 Conclusion 114 7. Scope. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 Scope Versus Existence 116 Lexical Versus Dynamic Scoping 116 Global Scope 117 Block Scope 119 Variable Masking 119 Functions, Closures, and Lexical Scope 121 Immediately Invoked Function Expressions 122 Function Scope and Hoisting 123 Function Hoisting 125 The Temporal Dead Zone 126 Strict Mode 126 Conclusion 127 8. Arrays and Array Processing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 A Review of Arrays 129 Array Content Manipulation 130 Adding or Removing Single Elements at the Beginning or End 131 Adding Multiple Elements at the End 131 Getting a Subarray 132 Adding or Removing Elements at Any Position 132 Cutting and Replacing Within an Array 132 Filling an Array with a Specific Value 133 Reversing and Sorting Arrays 133 Array Searching 134 The Fundamental Array Operations: map and filter 136 Array Magic: reduce 138 Array Methods and Deleted or Never-Defined Elements 141 String Joining 141 Conclusion 142 viii | Table of Contents
📄 Page
11
9. Objects and Object-Oriented Programming. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 Property Enumeration 145 for...in 146 Object.keys 146 Object-Oriented Programming 147 Class and Instance Creation 148 Dynamic Properties 149 Classes Are Functions 150 The Prototype 151 Static Methods 153 Inheritance 154 Polymorphism 155 Enumerating Object Properties, Revisited 156 String Representation 157 Multiple Inheritance, Mixins, and Interfaces 157 Conclusion 159 10. Maps and Sets. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 Maps 161 Weak Maps 163 Sets 164 Weak Sets 165 Breaking the Object Habit 165 11. Exceptions and Error Handling. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 The Error Object 167 Exception Handling with try and catch 168 Throwing Errors 169 Exception Handling and the Call Stack 169 try...catch...finally 171 Let Exceptions Be Exceptional 172 12. Iterators and Generators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 The Iteration Protocol 175 Generators 177 yield Expressions and Two-Way Communication 178 Generators and return 180 Conclusion 180 13. Functions and the Power of Abstract Thinking. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 Functions as Subroutines 181 Functions as Subroutines That Return a Value 182 Table of Contents | ix
📄 Page
12
Functions as…Functions 183 So What? 185 Functions Are Objects 186 IIFEs and Asynchronous Code 187 Function Variables 189 Functions in an Array 191 Pass a Function into a Function 192 Return a Function from a Function 193 Recursion 194 Conclusion 195 14. Asynchronous Programming. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 The Analogy 198 Callbacks 198 setInterval and clearInterval 199 Scope and Asynchronous Execution 200 Error-First Callbacks 201 Callback Hell 202 Promises 203 Creating Promises 204 Using Promises 204 Events 206 Promise Chaining 208 Preventing Unsettled Promises 209 Generators 210 One Step Forward and Two Steps Back? 213 Don’t Write Your Own Generator Runner 214 Exception Handling in Generator Runners 214 Conclusion 215 15. Date and Time. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 Dates, Time Zones, Timestamps, and the Unix Epoch 217 Constructing Date Objects 218 Moment.js 219 A Practical Approach to Dates in JavaScript 220 Constructing Dates 220 Constructing Dates on the Server 220 Constructing Dates in the Browser 221 Transmitting Dates 221 Displaying Dates 222 Date Components 223 Comparing Dates 224 x | Table of Contents
📄 Page
13
Date Arithmetic 224 User-Friendly Relative Dates 225 Conclusion 225 16. Math. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 Formatting Numbers 227 Fixed Decimals 228 Exponential Notation 228 Fixed Precision 228 Different Bases 229 Advanced Number Formatting 229 Constants 229 Algebraic Functions 230 Exponentiation 230 Logarithmic Functions 230 Miscellaneous 231 Pseudorandom Number Generation 232 Trigonometric Functions 232 Hyperbolic Functions 233 17. Regular Expressions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235 Substring Matching and Replacing 235 Constructing Regular Expressions 236 Searching with Regular Expressions 237 Replacing with Regular Expressions 237 Input Consumption 238 Alternation 240 Matching HTML 240 Character Sets 241 Named Character Sets 242 Repetition 243 The Period Metacharacter and Escaping 244 A True Wildcard 244 Grouping 245 Lazy Matches, Greedy Matches 246 Backreferences 247 Replacing Groups 248 Function Replacements 249 Anchoring 251 Word Boundary Matching 251 Lookaheads 252 Constructing Regexes Dynamically 253 Table of Contents | xi
📄 Page
14
Conclusion 254 18. JavaScript in the Browser. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255 ES5 or ES6? 255 The Document Object Model 256 Some Tree Terminology 259 DOM “Get” Methods 259 Querying DOM Elements 260 Manipulating DOM Elements 261 Creating New DOM Elements 261 Styling Elements 262 Data Attributes 263 Events 264 Event Capturing and Bubbling 265 Event Categories 268 Ajax 269 Conclusion 272 19. jQuery. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273 The Almighty Dollar (Sign) 273 Including jQuery 274 Waiting for the DOM to Load 274 jQuery-Wrapped DOM Elements 275 Manipulating Elements 275 Unwrapping jQuery Objects 277 Ajax 278 Conclusion 278 20. Node. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 Node Fundamentals 279 Modules 280 Core Modules, File Modules, and npm Modules 282 Customizing Modules with Function Modules 284 Filesystem Access 286 Process 289 Operating System 291 Child Processes 292 Streams 293 Web Servers 294 Conclusion 296 xii | Table of Contents
📄 Page
15
21. Object Property Configuration and Proxies. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 Accessor Properties: Getters and Setters 297 Object Property Attributes 299 Protecting Objects: Freezing, Sealing, and Preventing Extension 301 Proxies 304 Conclusion 306 22. Additional Resources. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307 Online Documentation 307 Periodicals 308 Blogs and Tutorials 308 Stack Overflow 309 Contributing to Open Source Projects 311 Conclusion 311 A. Reserved Words. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313 B. Operator Precedence. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319 Table of Contents | xiii
📄 Page
16
(This page has no text content)
📄 Page
17
Preface Even though this is my second book on technologies in the JavaScript ecosystem, I still find myself somewhat surprised at my role as a JavaScript expert and evangelist. Like so many programmers, I held a strong prejudice against JavaScript up until about 2012. To do such an about-face still feels a little disorienting. My prejudice was for the usual reasons: I considered JavaScript a “toy” language (without really learning it properly, and therefore not knowing of what I spoke) that was practiced by dangerous, sloppy, untrained amateur programmers. There is a little truth in both of these reasons. ES6 was developed quickly, and even its inventor Bren‐ dan Eich admits there are things that he didn’t get right the first time around—and by the time he realized it, too many people were relying on the problematic behavior for him to effectively change it (show me the language that doesn’t suffer from this prob‐ lem, however). As for the second reason, JavaScript did make programming suddenly accessible. Not only did everyone have a browser, but with only a little effort, they could see the JavaScript that enabled the websites that were rapidly proliferating on the Web. People learned by trial and error, by reading each other’s code and—in so many cases—emulating poorly written code with insufficient understanding. I’m glad I have learned enough about JavaScript to recognize that—far from being a toy language—it is based on extremely solid foundations, and is powerful, flexible, and expressive. I’m also glad I have come to embrace the accessibility that JavaScript brings. I certainly hold no animosity toward amateurs: everyone has to start some‐ where, programming is a profitable skill, and a career in programming has many advantages. To the new programmer, the amateur, I say this: there is no shame in being an ama‐ teur. There is some shame in staying an amateur (if you make programming your profession, certainly). If you want to practice programming, practice it. Learn every‐ thing you can, from every source you can. Keep an open mind and—perhaps most importantly—question everything. Question every expert. Question every experi‐ enced programmer. Constantly ask “Why?” xv
📄 Page
18
1 Eich confessed in a 2014 interview to enjoying thumbing his nose at Sun Microsystems, who “hated Java‐ Script.” For the most part, I have tried to keep this book to the “facts” of JavaScript, but it is impossible to completely avoid opinion. Where I offer opinions, take them for what they are. You are welcome to disagree, and you are encouraged to seek out the opin‐ ions of other experienced developers. You are learning JavaScript at a very exciting time. The Web is leaving its infancy (technically speaking), and web development isn’t the confusing, complicated Wild West that it was 5 and 10 years ago. Standards like HTML5 and ES6 are making it easier to learn web development, and easier to develop high-quality applications. Node.js is extending the reach of JavaScript beyond the browser, and now it is a viable choice for system scripting, desktop application development, backend web develop‐ ment, and even embedded applications. Certainly I haven’t had this much fun pro‐ gramming since I started in the mid-1980s. A Brief History of JavaScript JavaScript was developed by Brendan Eich, a developer at Netscape Communications Corporation, in 1995. Its initial development was very rapid, and much of the criti‐ cism leveled at JavaScript has cited the lack of planning foresight during its develop‐ ment. However, Brendan Eich was not a dabbler: he had a solid foundation in computer science, and incorporated remarkably sophisticated and prescient ideas into JavaScript. In many ways, it was ahead of its time, and it took 15 years for main‐ stream developers to catch on to the sophistication the language offered. JavaScript started life with the name Mocha, and was briefly named LiveScript before being officially renamed to JavaScript in a Netscape Navigator release in 1995. The word “Java” in “JavaScript” was not coincidental, but it is confusing: aside from a common syntactic ancestry, JavaScript has more in common with Self (a prototype- based language developed at Xerox PARC in the mid-’80s) and Scheme (a language developed in the 1970s by Guy Steele and Gerald Sussman, which was in turn heavily influenced by Lisp and ALGOL) than with Java. Eich was familiar with both Self and Scheme, and used some of their forward-thinking paradigms in developing Java‐ Script. The name JavaScript was partially a marketing attempt to tie into the success Java was enjoying at the time.1 In November 1996, Netscape announced that they had submitted JavaScript to Ecma, a private, international nonprofit standards organization that carries significant influ‐ ence in the technology and communications industries. Ecma International pub‐ lished the first edition of the ECMA-26 specification, which was, in essence, JavaScript. xvi | Preface
📄 Page
19
The relationship between Ecma’s specifications—which specify a language called ECMAScript—and JavaScript is mostly academic. Technically, JavaScript is an imple‐ mentation of ECMAScript, but for practical purposes, JavaScript and ECMAScript can be thought of interchangeably. The last major ECMAScript version was 5.1 (generically referred to as ES5), pub‐ lished in June 2011. Browsers “in the wild” that are old enough not to support ECMAScript 5.1 have fallen well below the single digits, and it’s safe to say that ECMAScript 5.1 is the current lingua franca of the Web. ECMAScript 6 (ES6)—which is the focus of this book—was published by Ecma Inter‐ national in June 2015. The working name for the specification prior to publication was “Harmony,” and you will hear ES6 referred to as “Harmony,” “ES6 Harmony,” “ES6,” “ES2015,” and “ECMAScript 2015.” In this book, we will refer to it simply as ES6. ES6 If ES5 is the current lingua franca of the Web, the attentive reader might be wonder‐ ing why this book focuses on ES6. ES6 represents a significant advancement in the JavaScript language, and some of ES5’s major shortcomings are addressed in ES6. I think you will find that ES6 is gen‐ erally a much more pleasant and powerful language to work with (and ES5 was quite enjoyable to start with). Also—thanks to transcompilers—you can write ES6 today and transcompile it to “web-compatible” ES5. With ES6 finally published, browser support for it will grow steadily, and at some point, transcompilation will no longer be necessary to reach a broad audience (I am not foolish enough to make a prediction—even a rough one—about when that will happen). What’s clear is that ES6 represents the future of JavaScript development, and by investing your time in learning it now, you will be prepared for the future, with trans‐ compilers preventing us from sacrificing portability now. However, not every developer will have the luxury of writing ES6 today. It’s possible that you’re working on a very large existing ES5 code base that would be prohibitively expensive to convert to ES6. And some developers simply won’t wish to go through the extra effort involved in transcompilation. With the exception of Chapter 1, this book will cover ES6, not ES5. Where appropri‐ ate, I will point out where ES6 differs from ES5, but there will not be side-by-side code examples, or extensive discussion of doing things “the ES5 way” when there is a better way in ES6. If you fall into that category of programmers who, for whatever Preface | xvii
📄 Page
20
reason, need to stick to ES5, this may not be the book for you (though I hope you will return to it at some point in the future!). The editorial choice to focus on ES6 was made carefully. The improvements in ES6 are significant enough that it would have been difficult to maintain a clear pedagogi‐ cal framework. In short, a book that attempts to cover ES5 and ES6 would do both topics a disservice. Who This Book Is For This book is primarily for readers who already have some experience with program‐ ming (even an introductory programming class, or an online course). If you’re new to programming, this book will be helpful, but you might want to supplement it with an introductory text or class. Those who already have some JavaScript experience (especially if it’s only in ES5) will find a practical and thorough coverage of important language concepts. Programmers who are coming from another language should feel right at home with the content in this book. This book does attempt to comprehensively cover the language features, related tools, techniques, and paradigms that drive modern JavaScript development. Therefore, the material in this book necessarily ranges from the simple and straightforward (vari‐ ables, control flow, functions) to the complicated and esoteric (asynchronous pro‐ gramming, regular expressions). Depending on your level of experience, you may find some chapters more challenging than others: the beginning programmer will no doubt need to revisit some of the material more than once. What This Book Is Not This book is not a comprehensive reference to JavaScript or its related libraries. The Mozilla Developer Network (MDN) maintains an excellent, thorough, up-to-date, and free online JavaScript reference, which will be referenced liberally throughout this book. If you prefer a physical book, David Flanagan’s JavaScript: The Definitive Guide is quite comprehensive (though it does not cover ES6 at the time of this writ‐ ing). Conventions Used in This Book The following typographical conventions are used in this book: Italic Indicates new terms, URLs, email addresses, filenames, and file extensions. xviii | Preface