Clean Code in JavaScript: Develop reliable, maintainable, and robust JavaScript
JavaScript & TypeScript
Softwarequalität

Clean Code in JavaScript: Develop reliable, maintainable, and robust JavaScript

James Padolsey, 2020

Inhaltsverzeichnis des Buches

  • Preface
  • Who this book is for
  • What this book covers
  • To get the most out of this book
  • Download the example code files
  • Download the color images
  • Conventions used
  • Get in touch
  • Reviews
  • Section 1: What is Clean Code Anyway?
  • Setting the Scene
  • Why we write code
  • Code as intent
  • Who is the user?
  • What is the problem?
  • Truly understanding the problem domain
  • Writing code for humans
  • Communicating intent
  • Readability
  • Meaningful abstractions
  • The tower of abstraction
  • The layers of clean code
  • Summary
  • The Tenets of Clean Code
  • Reliability
  • Correctness
  • Stability
  • Resilience
  • Efficiency
  • Time
  • Space
  • Efficiency's effects
  • Maintainability
  • Adaptability
  • Familiarity
  • Usability
  • User stories
  • Intuitive design
  • Accessibility
  • Summary
  • The Enemies of Clean Code
  • Enemy #1 JavaScript
  • Enemy #2 Management
  • Pressure to ship
  • Bad metrics
  • Lack of ownership
  • Enemy #3 Self
  • Showing off with syntax
  • Stubborn opinions
  • Imposter syndrome
  • Enemy #4 The cargo cult
  • Cargo culting code
  • Cargo culting tools and libraries
  • Summary
  • SOLID and Other Principles
  • The Law of Demeter
  • SOLID
  • Single responsibility principle
  • Open-closed principle
  • Liskov substitution principle
  • Interface segregation principle
  • Dependency inversion principle
  • The abstraction principle
  • Over-abstraction
  • Under-abstraction
  • Balanced abstraction
  • Functional programming principles
  • Functional purity
  • Immutability
  • Summary
  • Naming Things Is Hard
  • What's in a name?
  • Purpose
  • Concept
  • Contract
  • Naming anti-patterns
  • Needlessly short names
  • Needlessly exotic names
  • Needlessly long names
  • Consistency and hierarchy
  • Techniques and considerations
  • Hungarian notation
  • Naming and abstracting functions
  • Three bad names
  • Summary
  • Section 2: JavaScript and Its Bits
  • Primitive and Built-In Types
  • Primitive types
  • Immutability of primitives
  • Primitive wrappers
  • The falsy primitives
  • Number
  • String
  • Boolean
  • BigInt
  • Symbol
  • null
  • undefined
  • Objects
  • Property names
  • Property descriptors
  • Map and WeakMap
  • The prototype
  • When and how to use objects
  • Functions
  • Syntactic context
  • Function bindings and this
  • Execution context
  • super
  • new.target
  • arguments
  • Function names
  • Function declarations
  • Function expressions
  • Arrow functions
  • Immediately Invoked Function Expressions
  • Method definitions
  • Async functions
  • Generator functions
  • Arrays and iterables
  • Array-like objects
  • Set and WeakSet
  • Iterable protocol
  • RegExp
  • Regular expression 101
  • RegExp flags
  • Methods accepting RegExp
  • RegExp methods and lastIndex
  • Stickiness
  • Summary
  • Dynamic Typing
  • Detection
  • The typeof operator
  • Type-detecting techniques
  • Detecting Booleans
  • Detecting numbers
  • Detecting strings
  • Detecting undefined
  • Detecting null
  • Detecting null or undefined
  • Detecting arrays
  • Detecting instances
  • Detecting plain objects
  • Conversion, coercion, and casting
  • Converting into a Boolean
  • Converting into a String
  • Converting into a Number
  • Converting into a primitive
  • Summary
  • Operators
  • What is an operator?
  • Operator arity
  • Operator function
  • Operator precedence and associativity
  • Arithmetic and numeric operators
  • The addition operator
  • Both operands are numbers
  • Both operands are strings
  • One operand is a string
  • One operand is a non-primitive
  • Conclusion - know your operands!
  • The subtraction operator
  • The division operator
  • The multiplication operator
  • The remainder operator
  • The exponentiation operator
  • The unary plus operator
  • The unary minus operator
  • Logical operators
  • The logical NOT operator
  • The logical AND operator
  • The logical OR operator
  • Comparative operators
  • Abstract equality and inequality
  • Strict equality and inequality
  • Greater than and less than
  • Lexicographic comparison
  • Numeric comparison
  • The instanceof operator
  • The in operator
  • Assignment operators
  • Increment and decrement (prefix and postfix) operators
  • Prefix increment/decrement
  • Postfix increment/decrement
  • Destructuring assignment
  • Property access operators
  • Direct property access
  • Computed property access
  • Other operators and syntax
  • The delete operator
  • The void operator
  • The new operator
  • The spread syntax
  • The comma operator
  • Grouping
  • Bitwise operators
  • Summary
  • Parts of Syntax and Scope
  • Expressions, statements, and blocks
  • Expressions
  • Statements
  • Forming statements with semicolons
  • Blocks
  • Scopes and declarations
  • Variable declarations
  • Let declarations
  • Const declarations
  • Function declarations
  • Closures
  • Summary
  • Control Flow
  • What is control flow?
  • Imperative versus declarative programming
  • The movement of control
  • Invocation
  • Returning
  • Yielding
  • Yielding to a yield
  • Complexity of yielding
  • Breaking
  • Continuing
  • Throwing
  • Statements of control flow
  • The if statement
  • The for statement
  • Conventional for
  • for...in
  • for...of
  • The while statement
  • The do...while statement
  • The switch statement
  • Breaking and fallthrough
  • Returning from a switch directly
  • Case blocks
  • Multivariant conditions
  • Handling cyclomatic complexity
  • Simplifying conditional spaghetti
  • Asynchronous control flow
  • The Event Loop
  • Native asynchronous APIs
  • Callbacks
  • Event subscribing/emitting
  • Promises
  • async and await
  • Summary
  • Section 3: Crafting Abstractions
  • Design Patterns
  • The perspective of a designer
  • Architectural design patterns
  • MVC
  • A working example of MVC
  • MVVM
  • MV\* and the nature of software
  • JavaScript modules
  • Modular design patterns
  • Constructor patterns
  • When to use the Constructor pattern
  • Inheritance with the Constructor pattern
  • The Class pattern
  • When to use the Class pattern
  • Static methods
  • Public and private fields
  • Extending classes
  • Mixing-in classes
  • Accessing a super-class
  • The Prototype pattern
  • When to use the Prototype pattern
  • The Revealing Module pattern
  • The Conventional Module pattern
  • When to use the Conventional Module pattern
  • The Singleton Class pattern
  • When to use the Singleton Class pattern
  • Planning and harmony
  • Summary
  • Real-World Challenges
  • The DOM and single-page applications
  • DOM binding and reconciliation
  • DOM reconciliation
  • React's approach
  • Messaging and data propagation
  • Frontend routing
  • Dependency management
  • Module definition - then and now
  • npm and package.json
  • Bundling and serving
  • Security
  • Cross-Site Scripting
  • Content Security Policy
  • Subresource Integrity
  • Cross-Site Request Forgery
  • Other security vulnerabilities
  • Summary
  • Section 4: Testing and Tooling
  • The Landscape of Testing
  • What is a test?
  • The simple assertion
  • Many moving parts
  • Types of testing
  • Unit testing
  • Integration testing
  • E2E and functional testing
  • Test-Driven Development
  • Summary
  • Writing Clean Tests
  • Testing the right thing
  • Writing intuitive assertions
  • Creating clear hierarchies
  • Providing final clarity
  • Creating clean directory structures
  • Summary
  • Tools for Cleaner Code
  • Linters and formatters
  • Static typing
  • E2E testing tools
  • Automated builds and CI
  • Summary
  • Section 5: Collaboration and Making Changes
  • Documenting Your Code
  • Aspects of clean documentation
  • Concept
  • Specification
  • Instruction
  • Usability
  • Documentation is everywhere
  • Writing for non-technical audiences
  • Summary
  • Other Peoples' Code
  • Inheriting code
  • Exploring and understanding
  • Making a flowchart
  • Finding structure and observing history
  • Stepping through the code
  • Asserting your assumptions
  • Making changes
  • Minimally invasive surgery
  • Encoding changes as tests
  • Dealing with third-party code
  • Selection and understanding
  • Encapsulating and adapting third-party code
  • Summary
  • Communication and Advocacy
  • Planning and setting requirements
  • Understanding user needs
  • Quick prototypes and PoCs
  • Communication strategies
  • Listen and respond
  • Explain from the user's perspective
  • Have small and focused communications
  • Ask stupid questions and have wild ideas
  • Pair programming and 1:1s
  • Identifying issues and driving change
  • Raising bugs
  • Driving systemic change
  • Summary
  • Case Study
  • The problem
  • The design
  • The implementation
  • The Plant Selection application
  • Creating the REST API
  • Creating the client-side build process
  • Creating the component
  • Summary