art-of-comment

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Overview

概述

Every comment should earn its place. A good comment provides context the code alone cannot convey — why a decision was made, what trade-off was accepted, or how a non-obvious piece fits the bigger picture. A comment that merely restates the code is noise; remove or avoid it. When in doubt, prefer no comment over a redundant one.
每条注释都应当有其存在的价值。好的注释能够提供代码本身无法传递的上下文——为什么做出某个决策、接受了何种权衡,或者某个非直观的代码片段在整体架构中的作用。仅仅复述代码内容的注释属于冗余信息,应当删除或避免编写。如果拿不准,宁愿不写注释也不要写多余的注释。

Guidelines

指南

  • Comment only when needed. Do not add comments or JSDoc unless the code is non-obvious or you are explicitly asked. Self-explanatory code needs no narration.
  • Inline comments: ≤ 2 lines. Keep them terse — explain why, not what.
  • JSDoc: comprehensive yet concise. Document only what adds value: purpose, non-obvious parameters, return semantics, or usage examples. Omit what the signature already communicates.
  • Use
    /** ... */
    for reusable symbols.
    Functions, types, and constants referenced elsewhere should use JSDoc so IDE hover tooltips display the information.
  • Document trade-offs. When the implementation accepts a trade-off, explain the rationale and why it was worth taking.
  • No assumptions. Ground comments in library docs, project standards, or best practices — not guesses. Ask for clarification when unsure.
  • Stay consistent; never contradict. Match the tone and terminology of existing comments. Do not duplicate information already stated in a nearby comment — reference it instead.
  • 仅在必要时添加注释。 除非代码逻辑不直观或者有明确要求,否则不要添加注释或JSDoc。自解释的代码不需要额外说明。
  • 行内注释:≤ 2行。 保持简洁——解释为什么这么做,而非做了什么
  • JSDoc:全面且简洁。 仅记录有价值的内容:用途、非直观的参数、返回值语义或者使用示例。省略函数签名已经能表达的信息。
  • 可复用符号使用
    /** ... */
    格式注释。
    其他地方会引用的函数、类型、常量应当使用JSDoc,这样IDE的悬浮提示会展示相关信息。
  • 记录权衡取舍。 如果实现方案接受了某种权衡,要解释背后的逻辑以及这么做的合理性。
  • 不要主观臆断。 注释内容要基于库文档、项目规范或最佳实践,而非猜测。不确定时请询问确认。
  • 保持一致,切勿矛盾。 与现有注释的语气和术语保持统一。不要重复邻近注释已经说明的内容,可引用对应的注释。

Example

示例

The annotated snippet below highlights common comment pitfalls alongside good practice.
typescript
// (1) Calculate chart segments based on priority: verified > registered > rejected
const getChartSegments = (): {
  value: number
  color: string
  backgroundColor?: string
  badgeLabel?: string
}[] => {
  const verified = data?.verified ?? 0
  const registered = data?.registered ?? 0
  const rejected = data?.rejected ?? 0
  const total = verified + registered + rejected

  // (2) If all values are 0, show full gray circle
  if (total === 0) {
    return [{ value: 1, color: colors.palette.lightGray }]
  }

  // (3) Filter out zero values to prevent empty segments
  const segments = []

  // (4) Priority order: verified > registered > rejected
  if (verified > 0) {
    segments.push({
      value: verified,
      color: '#01C58A',
      backgroundColor: '#D6F6EC',
      badgeLabel: `${verified} Aset Terdata`,
    })
  }
  if (registered > 0) {
    segments.push({
      value: registered,
      color: '#FF9E00',
      backgroundColor: '#FFF1DB',
      badgeLabel: `${registered} Belum Diverif`,
    })
  }
  if (rejected > 0) {
    segments.push({
      value: rejected <= 2 ? 2 : rejected, // (5) Minimum visible segment size of 2
      color: '#FF5264',
      backgroundColor: '#FFECEC',
      badgeLabel: `${rejected} Ditolak`,
    })
  }
#VerdictWhy
1Good intent, wrong syntax. Clearly summarizes purpose and priority order — but should use
/** ... */
so the description appears on hover where
getChartSegments
is called.
2Remove. The condition and return value are self-explanatory; the comment adds nothing.
3Borderline. States the obvious, but may be acceptable as a signpost when debugging segment logic — acceptable only if it conveys intent the code cannot.
4Remove — duplicates (1). The priority order is already documented above; repeating it creates a maintenance burden. Reference the earlier comment if needed.
5Good. Concisely explains a non-obvious workaround and its effect.
下方带标注的代码片段展示了常见的注释误区以及最佳实践。
typescript
// (1) Calculate chart segments based on priority: verified > registered > rejected
const getChartSegments = (): {
  value: number
  color: string
  backgroundColor?: string
  badgeLabel?: string
}[] => {
  const verified = data?.verified ?? 0
  const registered = data?.registered ?? 0
  const rejected = data?.rejected ?? 0
  const total = verified + registered + rejected

  // (2) If all values are 0, show full gray circle
  if (total === 0) {
    return [{ value: 1, color: colors.palette.lightGray }]
  }

  // (3) Filter out zero values to prevent empty segments
  const segments = []

  // (4) Priority order: verified > registered > rejected
  if (verified > 0) {
    segments.push({
      value: verified,
      color: '#01C58A',
      backgroundColor: '#D6F6EC',
      badgeLabel: `${verified} Aset Terdata`,
    })
  }
  if (registered > 0) {
    segments.push({
      value: registered,
      color: '#FF9E00',
      backgroundColor: '#FFF1DB',
      badgeLabel: `${registered} Belum Diverif`,
    })
  }
  if (rejected > 0) {
    segments.push({
      value: rejected <= 2 ? 2 : rejected, // (5) Minimum visible segment size of 2
      color: '#FF5264',
      backgroundColor: '#FFECEC',
      badgeLabel: `${rejected} Ditolak`,
    })
  }
#判定原因
1初衷很好,但语法错误。 清晰概括了函数用途和优先级顺序,但应当使用
/** ... */
格式,这样调用
getChartSegments
时描述会出现在悬浮提示中。
2建议删除。 条件判断和返回值都是自解释的,该注释没有提供额外价值。
3可留可删。 描述的是显而易见的内容,但如果作为调试分段逻辑的标识是可以接受的——仅当它能传递代码无法表达的意图时保留。
4建议删除——与(1)重复。 优先级顺序已经在上方说明,重复会增加维护成本。如有需要可引用前面的注释。
5优秀。 简洁地解释了一个非直观的兼容处理及其作用。