Refactoring-Javascript.Pdf

Refactoring-Javascript.Pdf

Refactoring JavaScript Turning Bad Code into Good Code Evan Burchard Refactoring JavaScript by Evan Burchard Copyright © 2017 Evan Burchard. 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 promotion- al use. Online editions are also available for most titles (http://oreilly.com/ safari). For more information, contact our corporate/institutional sales depart- ment: 800-998-9938 or [email protected]. • Editors: Nan Barber and Allyson MacDonald • Production Editor: Kristen Brown • Copyeditor: Rachel Monaghan • Proofreader: Rachel Head • Indexer: Ellen Troutman-Zaig • Interior Designer: David Futato • Cover Designer: Karen Montgomery • Illustrator: Rebecca Demarest • March 2017: First Edition Revision History for the First Edition • 2017-03-10: First Release See http://oreilly.com/catalog/errata.csp?isbn=9781491964927 for release details. The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. Refactoring JavaScript, the cover image, 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 pub- lisher and the author disclaim all responsibility for errors or omissions, includ- ing without limitation responsibility for damages resulting from the use of or re- liance 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 con- tains 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 com- plies with such licenses and/or rights. 978-1-491-96492-7 [LSI] For Jade, again and always. Table of Contents Foreword xiii Preface xv CHAPTER 1: What Is Refactoring? 1 How Can You Guarantee Behavior Doesn’t Change? 1 Why Don’t We Care About Details of Implementation? 3 Why Don’t We Care About Unspecified and Untested Behavior? 4 Why Don’t We Care About Performance? 5 What Is the Point of Refactoring if Behavior Doesn’t Change? 7 Balancing Quality and Getting Things Done 7 What Is Quality and How Does It Relate to Refactoring? 7 Refactoring as Exploration 10 What Is and Isn’t Refactoring 11 Wrapping Up 11 CHAPTER 2: Which JavaScript Are You Using? 13 Versions and Specifications 14 Platforms and Implementations 15 Precompiled Languages 17 Frameworks 18 Libraries 19 What JavaScript Do You Need? 20 What JavaScript Are We Using? 20 v Table of Contents Wrapping Up 21 CHAPTER 3: Testing 23 The Many Whys of Testing 25 The Many Ways of Testing 27 Manual Testing 28 Documented Manual Testing 28 Approval Tests 29 End-to-End Tests 31 Unit Tests 32 Nonfunctional Testing 34 Other Test Types of Interest 35 Tools and Processes 35 Processes for Quality 36 Tools for Quality 42 Wrapping Up 46 CHAPTER 4: Testing in Action 47 New Code from Scratch 49 New Code from Scratch with TDD 57 Untested Code and Characterization Tests 77 Debugging and Regression Tests 83 Wrapping Up 92 CHAPTER 5: Basic Refactoring Goals 93 Function Bulk 96 Inputs 100 Outputs 108 Side Effects 112 Context Part 1: The Implicit Input 115 this in Strict Mode 116 Context Part 2: Privacy 124 Is There Privacy in JavaScript? 140 vi Table of Contents Wrapping Up 142 CHAPTER 6: Refactoring Simple Structures 143 The Code 145 Our Strategy for Confidence 148 Renaming Things 151 Useless Code 155 Dead Code 155 Speculative Code and Comments 156 Whitespace 157 Do-Nothing Code 158 Debugging/Logging Statements 162 Variables 162 Magic Numbers 163 Long Lines: Part 1 (Variables) 164 Inlining Function Calls 165 Introducing a Variable 167 Variable Hoisting 169 Strings 173 Concatenating, Magic, and Template Strings 173 Regex Basics for Handling Strings 174 Long Lines: Part 2 (Strings) 175 Working with Arrays: Loops, forEach, map 177 Long Lines: Part 3 (Arrays) 178 Which Loop to Choose? 180 Better Than Loops 183 Wrapping Up 185 CHAPTER 7: Refactoring Functions and Objects 187 The Code (Improved) 187 Array and Object Alternatives 190 Array Alternative: Sets 191 Array Alternative: Objects 191 Object Alternative: Maps 194 vii Table of Contents Array Alternative: Bit Fields 198 Testing What We Have 199 Our Setup Test 201 Characterization Tests for classify 203 Testing the welcomeMessage 205 Testing for labelProbabilities 206 Extracting Functions 207 Getting Away from Procedural Code 207 Extracting and Naming Anonymous Functions 213 Function Calls and Function Literals 215 Streamlining the API with One Global Object 216 Extracting the classifier Object 220 Inlining the setup Function 221 Extracting the songList Object 222 Handling the Remaining Global Variables 223 Making Data Independent from the Program 224 Scoping Declarations: var, let, and const 225 Bringing classify into the classifier 226 Untangling Coupled Values 239 Objects with Duplicate Information 245 Bringing the Other Functions and Variables into classifier 246 Shorthand Syntax: Arrow, Object Function, and Object 253 Getting New Objects with Constructor Functions 262 Constructor Functions Versus Factory Functions 265 A class for Our Classifier 270 Choosing Our API 273 Time for a Little Privacy? 275 Adapting the Classifier to a New Problem Domain 278 Wrapping Up 281 CHAPTER 8: Refactoring Within a Hierarchy 283 About “CRUD Apps” and Frameworks 283 Let’s Build a Hierarchy 284 Let’s Wreck Our Hierarchy 293 viii Table of Contents Constructor Functions 293 Object Literals 297 Factory Functions 299 Evaluating Your Options for Hierarchies 301 Inheritance and Architecture 302 Why Do Some People Hate Classes? 303 What About Multiple Inheritance? 304 Which Interfaces Do You Want? 307 Has-A Relationships 309 Inheritance Antipatterns 310 Hyperextension 311 Goat and Cabbage Raised by a Wolf 314 Wrapping Up 319 CHAPTER 9: Refactoring to OOP Patterns 321 Template Method 322 A Functional Variant 325 Strategy 326 State 329 null Object 336 Wrapper (Decorator and Adapter) 345 Facade 353 Wrapping Up 356 CHAPTER 10: Asynchronous Refactoring 359 Why Async? 359 Fixing the Pyramid of Doom 362 Extracting Functions into a Containing Object 362 Testing Our Asynchronous Program 365 Additional Testing Considerations 368 Callbacks and Testing 371 Basic CPS and IoC 371 Callback Style Testing 373 Promises 377 ix Table of Contents The Basic Promise Interface 377 Creating and Using Promises 378 Testing Promises 381 Wrapping Up 383 CHAPTER 11: Functional Refactoring 385 The Restrictions and Benefits of Functional Programming 386 Restrictions 386 Benefits 388 The Future (Maybe) of Functional Programming 393 The Basics 393 Avoiding Destructive Actions, Mutation, and Reassignment 393 Don’t return null 404 Referential Transparency and Avoiding State 405 Handling Randomness 409 Keeping the Impure at Bay 409 Advanced Basics 412 Currying and Partial Application (with Ramda) 412 Function Composition 416 Types: The Bare Minimum 420 Burritos 423 Introducing Sanctuary 425 The null Object Pattern, Revisited! 427 Functional Refactoring with Maybe 433 Functional Refactoring with Either 436 Learning and Using Burritos 439 Moving from OOP to FP 441 Return of the Naive Bayes Classifier 441 Rewrites 445 Wrapping Up 446 CHAPTER 12: Conclusion 449 Further Reading and Resources 451 x Table of Contents Index 457 xi Foreword I still remember reading Martin Fowler’s book Refactoring: Improving the Design of Existing Code when it came out in 1999. It was a revelation: I had never before seen code being considered to be something malleable. Programmers tend to have the urge to rewrite code bases from scratch, but this book argued that it is possible to evolve and clean up existing code via small, principled, and compa- ratively safe steps. While doing so, tests provide an additional safety net and enable you to move forward with confidence. One piece of advice from the book will always stick with me—whenever you code, always keep two kinds of activity completely separate: implementing new functionality and refactoring existing code. If you do that, you’ll avoid doing too many things at the same time and will produce less bugs. Refactoring JavaScript takes the ideas of refactoring and applies them to the world of JavaScript. JavaScript’s dynamic nature means that you need different techniques compared to more static languages such as Java. In Java, you have static typing. And inheritance and polymorphism are used quite often. For Java- Script, you often rely on static checking tools (such as ESLint and Flow) and can adapt objects flexibly according to your needs. Functional programming techni- ques are also more popular. Additionally, tests play an even more important role, but they also tend to be more lightweight. With all of these issues and more (e.g., asynchronous code), this book has you covered! Happy reading! —Axel Rauschmayer —November 2016 xiii Preface Welcome to Refactoring JavaScript. Throughout this book, we’ll be looking at ways to write better JavaScript, drawing inspiration from classical refactoring techniques while exploring various styles of coding. Why This Book Exists Like it or not, JavaScript is not going away. No matter what framework or “compiles-to-JS” language or library you use, bugs and performance concerns will always be an issue if the underlying quality of your JavaScript is poor. Re- writes, including porting to the framework of the month, are terribly expensive and unpredictable. The bugs won’t magically go away, and can happily repro- duce themselves in a new context. To complicate things further, features will get dropped, at least temporarily. This book provides clear guidance on how best to avoid these pathological approaches to writing JavaScript. Bad code doesn’t have to stay that way. And making it better doesn’t have to be intimidating or unreasonably expensive. Who This Book Is For This book is meant for programmers who have some experience writing bad code, and an interest in writing better code.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    499 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us