clean-code

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Clean Code for TypeScript/JavaScript

面向TypeScript/JavaScript的Clean Code实践

Practical patterns for writing and refactoring clean, maintainable TypeScript/JavaScript code.
提供编写、重构整洁可维护TypeScript/JavaScript代码的实用模式。

Code Smell Detection

代码异味检测

Naming Smells

命名异味

SmellExampleFix
Single-letter names
const d = new Date()
const createdAt = new Date()
Abbreviations
const usrMgr = ...
const userManager = ...
Generic names
data
,
info
,
temp
,
result
Name by what it represents
Misleading names
userList
(but it's a Set)
users
or
userSet
Encoding types
strName
,
arrItems
name
,
items
异味示例修复方案
单字母命名
const d = new Date()
const createdAt = new Date()
缩写命名
const usrMgr = ...
const userManager = ...
泛化命名
data
info
temp
result
按照实际代表的含义命名
误导性命名
userList
(实际是Set类型)
users
或者
userSet
类型嵌入命名
strName
arrItems
name
items

Function Smells

函数异味

SmellIndicatorRefactoring
Too many parameters>3 paramsExtract to options object
Flag arguments
process(data, true)
Split into separate functions
Side effects hiddenFunction does more than name suggestsRename or split
God function>20 lines or multiple responsibilitiesExtract smaller functions
Deep nesting>3 levels of indentationEarly returns, extract functions
异味特征重构方案
参数过多参数数量>3抽离为配置对象
标记参数
process(data, true)
拆分为独立函数
隐藏副作用函数实际功能与名称描述不符重命名或者拆分函数
上帝函数代码行数>20或承担多个职责抽离为多个更小的函数
深层嵌套缩进层级>3提前返回、抽离函数

Structure Smells

结构异味

SmellIndicatorRefactoring
Long file>300 linesSplit by responsibility
Feature envyFunction uses another object's data extensivelyMove to that object
Data clumpsSame group of params passed togetherExtract to type/class
Primitive obsessionUsing primitives for domain conceptsCreate value objects
Switch on type
if (type === 'A') ... else if (type === 'B')
Polymorphism or lookup
异味特征重构方案
文件过长代码行数>300按职责拆分文件
特性依恋函数大量使用其他对象的数据将函数移动到对应对象中
数据泥团同一组参数被反复传递抽离为类型/类
基础类型偏执对领域概念使用基础类型表示创建值对象
类型判断分支
if (type === 'A') ... else if (type === 'B')
多态或者查找表

Refactoring Patterns

重构模式

For detailed before/after code examples, see references/refactoring-patterns.md.
Quick reference:
  1. Guard clauses — Replace nested if/else with early returns
  2. Object lookup — Replace switch/if-else chains with Record mapping
  3. Options object — Replace >3 parameters with a single options object
  4. Named constants — Replace magic numbers/strings with descriptive constants
  5. Extract function — Break god functions into single-responsibility pieces
  6. Flatten ternaries — Replace nested ternaries with lookup or function
  7. Consolidate duplicates — Extract repeated logic into shared functions
  8. Simplify booleans — Return condition directly instead of if/else true/false
  9. Array methods — Replace manual loops with filter/map/reduce
  10. Destructure — Use destructuring for cleaner property access
如需查看详细的代码前后对比示例,请查看references/refactoring-patterns.md
快速参考:
  1. 守卫子句 — 用提前返回替代嵌套if/else
  2. 对象查找 — 用Record映射替代switch/if-else分支链
  3. 配置对象 — 用单个配置对象替代超过3个的入参
  4. 命名常量 — 用含义明确的常量替代魔术数字/字符串
  5. 函数抽取 — 将上帝函数拆分为多个单一职责的小函数
  6. 扁平化三元运算 — 用查找表或者函数替代嵌套三元运算
  7. 重复逻辑合并 — 将重复出现的逻辑抽离为共享函数
  8. 布尔值简化 — 直接返回条件判断结果,替代if/else返回true/false的写法
  9. 数组方法 — 用filter/map/reduce替代手动循环
  10. 解构 — 使用解构实现更简洁的属性访问

Naming Conventions

命名规范

Functions

函数

  • Actions: verb + noun →
    createUser
    ,
    validateInput
    ,
    fetchOrders
  • Booleans: is/has/can/should prefix →
    isValid
    ,
    hasPermission
    ,
    canEdit
  • Event handlers: handle + event →
    handleClick
    ,
    handleSubmit
  • Transformers: to/from/parse/format →
    toJSON
    ,
    fromDTO
    ,
    parseDate
  • 动作类:动词+名词 →
    createUser
    validateInput
    fetchOrders
  • 布尔返回类:使用is/has/can/should前缀 →
    isValid
    hasPermission
    canEdit
  • 事件处理类:handle+事件名 →
    handleClick
    handleSubmit
  • 转换类:to/from/parse/format前缀 →
    toJSON
    fromDTO
    parseDate

Variables

变量

  • Booleans: positive names →
    isEnabled
    not
    isNotDisabled
  • Arrays/collections: plural →
    users
    ,
    orderItems
  • Counts: noun + Count →
    retryCount
    ,
    errorCount
  • 布尔类型:使用肯定含义命名 → 用
    isEnabled
    而非
    isNotDisabled
  • 数组/集合类型:使用复数形式 →
    users
    orderItems
  • 计数类:名词+Count →
    retryCount
    errorCount

Constants

常量

  • Module-level: SCREAMING_SNAKE_CASE →
    MAX_RETRIES
    ,
    API_BASE_URL
  • Enum-like objects: PascalCase key, values match usage →
    Status.Active
  • 模块级别常量:全大写下划线分隔 →
    MAX_RETRIES
    API_BASE_URL
  • 类枚举对象:键使用大驼峰,值匹配使用场景 →
    Status.Active

Quick Refactoring Checklist

快速重构检查清单

When reviewing code for cleanliness:
  1. Names — Can you understand intent without reading implementation?
  2. Functions — Does each do exactly one thing? <20 lines?
  3. Parameters — More than 3? Extract to object
  4. Nesting — More than 2 levels? Use early returns
  5. Duplication — Same logic in 2+ places? Extract
  6. Magic values — Any unexplained numbers/strings? Name them
  7. Comments — Explaining "what"? Rewrite code to be self-explanatory
  8. Dead code — Commented-out code or unused vars? Delete
评审代码整洁度时可参考以下项:
  1. 命名 — 不看具体实现能否理解代码意图?
  2. 函数 — 每个函数是否只做一件事?代码行数是否<20?
  3. 参数 — 入参是否超过3个?可抽离为配置对象?
  4. 嵌套 — 嵌套层级是否超过2层?可使用提前返回优化?
  5. 重复 — 同一逻辑是否出现在2个以上位置?可抽离复用?
  6. 魔术值 — 是否存在无说明的数字/字符串?可命名为常量?
  7. 注释 — 注释是否在解释“做了什么”?可优化代码使其自解释?
  8. 死代码 — 是否存在注释掉的代码或者未使用的变量?可删除?

Anti-Patterns to Avoid

需要避免的反模式

Over-Engineering

过度工程

  • Don't create abstractions for single-use cases
  • Don't add configurability "for the future"
  • Don't wrap simple operations in utility functions
  • 不要为仅使用一次的场景创建抽象
  • 不要“为了未来可能的需求”额外添加可配置性
  • 不要把简单操作封装到多余的工具函数里

Under-Engineering

工程不足

  • Don't ignore repeated patterns (3+ occurrences = extract)
  • Don't leave deeply nested code unrefactored
  • Don't use
    any
    to avoid typing properly
  • 不要忽略重复出现的模式(出现3次及以上就可以抽离复用)
  • 不要留下深层嵌套的代码不重构
  • 不要用
    any
    来逃避正确的类型定义

Wrong Abstraction

错误抽象

  • Don't force inheritance when composition works
  • Don't create god classes that do everything
  • Don't split tightly coupled logic across files
  • 组合更合适时不要强行使用继承
  • 不要创建承担所有职责的上帝类
  • 不要把强耦合的逻辑拆分到多个文件中