JavaScript • Software Craft and Communication

Writing Comments — Write comments that explain intent and assumptions

Learn to write code comments that reveal the why behind your decisions, not just the what.

JavaScript emblem with code brackets, braces, and a code file.
Inside this lesson 10 sections 5 questions 5 figures

SECTION 1

Historical Context & Motivation

Since the earliest days of programming, developers have recognized that source code is read far more often than it is written. When you write a program, you might spend a few hours crafting a function, but your teammates — or even future-you — might read that function dozens of times over the life of a project. Code comments evolved as a way to embed human-readable explanations directly inside the source code, bridging the gap between what a machine executes and what a person needs to understand.

1958 • FORTRAN Introduces Comments

One of the first high-level languages, FORTRAN, allowed programmers to mark lines with a 'C' in column 1 to indicate a comment. This was revolutionary because assembly language had no standard comment syntax.

1972 • C Language and /* */ Syntax

The C programming language popularized block comments with /* and */. This syntax directly influenced JavaScript's comment style decades later.

1995 • JavaScript Is Born

Brendan Eich created JavaScript in just 10 days. It inherited both single-line (//) and multi-line (/* */) comment syntax from C and C++, making comments a first-class citizen in the language.

2001 • Agile & Clean Code Movements

The Agile Manifesto and later Robert C. Martin's 'Clean Code' book challenged developers to write self-documenting code and use comments only when they add genuine value — specifically to explain intent and assumptions.

2015+ • Modern JS Tooling and JSDoc

Tools like JSDoc, ESLint, and TypeScript use specially formatted comments to generate documentation and catch bugs automatically. Comments became not just notes for humans but instructions for tools.

Despite all of these advances, most beginner programmers still struggle with what to comment. They either write too many obvious comments that just restate the code, or they write none at all and leave future readers guessing. The central question this lesson addresses is: How do you write comments that genuinely help someone understand your code? The answer lies in explaining intent (why you did something) and assumptions (what conditions must be true for this code to work correctly).

SECTION 2

Core Principles of Effective Comments

Writing useful comments is a skill, not a chore. Great comments don't repeat the code — they add context that the code alone cannot convey. Think of comments as a conversation with the next person who reads your code, which might very well be yourself six months from now. The following principles form the foundation of comment-writing craft.

1

Explain WHY, Not WHAT

The code already shows what happens. A good comment explains the reasoning, motivation, or business rule behind a decision. Ask yourself: 'Would someone reading this code wonder why I chose this approach?'
2

State Your Assumptions

Every piece of code operates under invisible assumptions — that an input is never negative, that an array is sorted, or that a network response returns within 5 seconds. Making these assumptions explicit in a comment prevents bugs when conditions change.
3

Keep Comments Up-to-Date

A stale comment that contradicts the code is worse than no comment at all. Whenever you update a block of code, review its comments. If the logic changed, the explanation must change too.
4

Prefer Clear Code Over Comments

Before writing a comment, ask: 'Can I rename a variable or restructure the logic so this is obvious?' If yes, fix the code first. Comments should supplement clear code, not rescue confusing code.
5

Use the Right Format

JavaScript offers single-line comments (//) for brief notes, block comments (/* */) for longer explanations, and JSDoc (/** */) for formal documentation. Choose the format that matches the scope of your explanation.
✦

KEY TAKEAWAY

Think of code comments like margin notes in a textbook. The textbook text (your code) shows the facts and formulas. The margin notes (your comments) explain why the author chose that example, what tricky parts to watch out for, and what you should keep in mind. Without them, you'd understand the steps but miss the deeper story.

SECTION 3

Visual Explanation — Good vs. Bad Comments

The diagram below compares two approaches to commenting the same piece of code. On the left, you see comments that merely restate what the code does — these add visual clutter without adding understanding. On the right, the comments explain intent and assumptions, giving the reader genuine insight into the developer's reasoning.

Good vs. Bad Comments: Side-by-Side Comparison✗ BAD: Restates the Code// set x to 10let x = 10;// loop through the arrayfor (let i = 0; i < arr.length; i++)// check if age is greater than 18if (age > 18) { ... }Problems:• Adds no new information• Creates visual clutter• Must be updated if code changes✓ GOOD: Explains Intent & Assumptions// Retry limit — server docs recommend// no more than 10 attempts per sessionlet maxRetries = 10;// Process oldest orders first (FIFO)// Assumes arr is sorted by timestampfor (let i = 0; i < arr.length; i++)// Legal voting age in the US;// update if deploying internationallyif (age > 18) { ... }Benefits:• Explains WHY behind each choice• States hidden assumptions explicitly• Prevents future bugs from wrong guesses
On the left, each comment simply restates the code line below it — telling you nothing new. On the right, each comment reveals the reason behind the decision or an assumption the code depends on, giving readers crucial context they couldn't get from the code alone.

Notice the pattern: in the good examples, the variable name maxRetries already tells you what the value represents. The comment adds why it is set to 10 specifically and where that number came from. This is the essence of intent-driven commenting: the code handles the 'what,' and the comment handles the 'why.'

SECTION 4

How Intent & Assumption Comments Work

Understanding the mechanics behind effective commenting starts with recognizing the two fundamental types of hidden knowledge in any codebase: intent and assumptions. Intent is the purpose behind a decision — the business requirement, the algorithm choice, or the design trade-off. Assumptions are the conditions that must hold true for the code to work correctly, even though they aren't enforced by the code itself.

JavaScript Comment Syntax

JavaScript provides three standard comment formats. Single-line comments use // and extend to the end of the line. They are ideal for brief notes about a single statement. Multi-line comments use /* */ and can span multiple lines, making them suitable for longer explanations at the top of a function or file. JSDoc comments use /** */ and follow a structured format with tags like @param and @returns; tools can parse them to auto-generate documentation.

The Intent–Assumption Framework

When you sit down to comment a piece of code, run through two mental questions. First: "Why did I write this particular line or block this way?" If the answer isn't obvious from the code, write an intent comment. Second: "What must be true about the data, the environment, or the caller for this to work?" If there's a hidden dependency, write an assumption comment. These two questions cover the vast majority of situations where comments genuinely help.

The Intent–Assumption Decision FlowchartRead a line of codeIs the WHY obviousfrom the code?NoYesWrite INTENTcommentHiddenassumptions?YesNoWrite ASSUMPTIONcommentNo comment neededExamples of Each TypeINTENT:// Use binary search here for O(log n) — list can exceed 10k itemsASSUMPTION:// Assumes `users` is already sorted by lastName (done in fetchUsers)
This flowchart shows the two-question decision process. For every line or block, first check if the 'why' is obvious — if not, write an intent comment. Then check for hidden dependencies — if found, write an assumption comment. If both checks pass, no comment is needed.

SECTION 5

Classifying Comment Types in JavaScript

Not all comments serve the same purpose. Professional developers generally classify comments into several categories, and understanding these categories helps you decide which to use. The table below breaks down the most common types you'll encounter in JavaScript projects, with a focus on which ones genuinely add value.

Comment TypePurposeExampleValue Level
IntentExplains why a specific approach was chosen// Debounce to avoid flooding the API on each keystroke★★★ High
AssumptionStates a condition the code depends on but doesn't enforce// Assumes price is in USD cents, not dollars★★★ High
TODO / FIXMEMarks known issues or planned improvements// TODO: Add input validation for negative values★★ Medium
WarningAlerts about non-obvious consequences// WARNING: Mutates the original array in place★★ Medium
JSDocFormal documentation for functions, classes, and modules/** @param {string} name - User's display name */★★★ High
NarrationRestates what the code already says// increment i by 1★ Low / Avoid

Comment types ranked by the value they add to a JavaScript codebase

As you can see, intent comments and assumption comments are the most valuable because they capture knowledge that would otherwise exist only inside the original developer's head. Narration comments — the kind that say 'increment i' next to i++ — actively harm readability by adding noise without adding meaning. Your goal as a developing programmer should be to maximize high-value comments and eliminate narration.

💡

Tip: The 6-Month Test

Before you write a comment, ask yourself: 'If I come back to this code in six months, will I remember why I made this decision?' If the answer is no, write the comment. If the code already makes it clear, skip it.

SECTION 6

Worked Example — Commenting a Real Function

Let's walk through a complete example. Imagine you're building a web app for a school cafeteria, and you need a function that calculates the discounted price for students who qualify for free or reduced-price lunch. We'll start with uncommented code and progressively add intent and assumption comments.

Adding Intent & Assumption Comments to a Discount Function

  1. 1

    Step 1 — Read the Uncommented Code

    Here is the raw function without any comments: function calcLunchPrice(basePrice, studentId, discountTier) { if (discountTier === 'free') return 0; if (discountTier === 'reduced') return basePrice * 0.4; if (basePrice > 5.00) return basePrice - 0.50; return basePrice; } A reader can see WHAT the function does — it returns different prices based on a discount tier. But several questions remain unanswered.
    Key questions: Why 0.4? Why 5.00? Why −0.50? Where does discountTier come from?
  2. 2

    Step 2 — Identify Hidden Intent

    Ask: 'Why did the developer choose these specific numbers?' The 0.4 multiplier means students on 'reduced' lunch pay 40% of the base price. That isn't an arbitrary choice — it comes from the National School Lunch Program (NSLP) guidelines. The 0.50 discount for prices over $5.00 is a local cafeteria policy to encourage buying higher-priced healthy options. These are intent details that belong in comments.
    Intent identified: the 40% rate from NSLP guidelines, and the $0.50 incentive policy.
  3. 3

    Step 3 — Identify Hidden Assumptions

    Ask: 'What must be true for this code to work correctly?' The function assumes basePrice is a positive number in dollars (not cents). It assumes discountTier is one of exactly three values: 'free', 'reduced', or undefined/other. It also assumes the student's eligibility was already verified before this function was called.
    Assumptions identified: price in dollars, valid tier values, pre-verified eligibility.
  4. 4

    Step 4 — Write the Commented Version

    Now we add comments that capture intent and assumptions: /** * Calculates the lunch price after applying discount tiers. * Assumes `basePrice` is in US dollars (not cents) and is > 0. * Assumes `discountTier` is validated upstream by verifyEligibility(). * @param {number} basePrice - Menu price before discounts * @param {string} studentId - Used for audit logging (not pricing) * @param {string} discountTier - 'free', 'reduced', or undefined * @returns {number} Final price the student pays */ function calcLunchPrice(basePrice, studentId, discountTier) { // NSLP 'free' tier: student pays nothing if (discountTier === 'free') return 0; // NSLP 'reduced' tier: student pays 40% per federal guidelines if (discountTier === 'reduced') return basePrice * 0.4; // Cafeteria incentive: $0.50 off meals over $5 to encourage // choosing the premium healthy option (Policy #12, Sept 2024) if (basePrice > 5.00) return basePrice - 0.50; return basePrice; }
    Every comment now explains WHY, not WHAT. The JSDoc header captures all major assumptions.
  5. 5

    Step 5 — Verify Comment Quality

    Run through a final checklist. Does any comment simply restate the code? No — each one adds context about federal guidelines, local policy, or data expectations. Are assumptions called out? Yes — the JSDoc block states the unit (dollars, not cents) and where validation happens. Would a new teammate understand this function without asking you? Yes. The comments have done their job.
    Final result: a well-commented function that any developer can maintain with confidence.

SECTION 7

Strengths, Pitfalls, and Best Practices

Like any tool, comments can be used well or poorly. The difference between a helpful codebase and a frustrating one often comes down to comment quality. Understanding both the strengths and the common pitfalls of commenting will help you develop a balanced approach.

StrengthsPitfalls
Intent comments make code maintainable — future developers can modify logic without breaking hidden expectations.Stale comments that contradict the current code are worse than no comments, because they actively mislead readers.
Assumption comments prevent bugs by making invisible dependencies visible before they cause failures.Over-commenting every line creates visual noise and makes it harder to scan the actual logic.
JSDoc comments integrate with IDEs, enabling auto-complete tooltips and generated documentation.Using comments to explain bad code instead of fixing it ('comment crutch') hides deeper design problems.
TODO/FIXME markers help teams track technical debt and planned improvements in a discoverable way.Leaving commented-out code blocks in production clutters the file — use version control (Git) instead.

Strengths and pitfalls of code comments in JavaScript projects

✦

KEY TAKEAWAY

Think of comments like road signs on a highway. A sign that says 'Road' at the sight of a road is useless (that's a narration comment). But a sign that says 'Bridge freezes before road — reduce speed' is invaluable because it warns you about a hidden assumption (the bridge surface behaves differently) and tells you the intent (you should slow down). Write comments that are road signs, not labels.

SECTION 8

Connecting to Professional Practices

The commenting skills you've learned in this lesson form the foundation for professional software communication practices that you'll encounter as you advance. In real-world teams, comments are just one part of a broader documentation ecosystem that includes code reviews, commit messages, pull request descriptions, and technical design documents. The intent-and-assumption mindset applies to all of these formats.

This Lesson (Basics)Professional Level
Single-line // comments for intentADRs (Architecture Decision Records) that formally document design choices and their trade-offs
Assumption comments in codeContract-based programming with runtime assertions and TypeScript types that enforce assumptions
JSDoc for function documentationAuto-generated API documentation sites using tools like Storybook, Swagger, or TypeDoc
TODO markers for known issuesIssue trackers (GitHub Issues, Jira) with linked commits so every change traces back to a requirement

How basic comment practices scale into professional documentation workflows

As you move into AP Computer Science, college courses, or internships, you'll find that teams value developers who communicate clearly in code just as much as those who write clever algorithms. The two-question framework — "Why did I do this?" and "What must be true?" — will serve you well in every one of those contexts, whether you're writing a comment, a commit message, or a design document.

SECTION 9

Practice Problems

Question 1: CONCEPTUAL

Explain in your own words why the comment // add 1 to counter above the line counter += 1; is considered a poor comment. What kind of comment would be more useful here?
Show answer
The comment // add 1 to counter is a narration comment — it simply restates what the code already says in English, adding no new information. Anyone who can read JavaScript already knows that counter += 1 increments the counter. A better comment would explain WHY the counter is being incremented, such as // Track failed login attempts for the lockout policy (max 5). This version tells the reader the purpose behind the increment and references a specific business rule, which is information they couldn't get from the code alone.

Question 2: BASIC

Look at this code and write one intent comment and one assumption comment for it: function getShippingCost(weight) { if (weight <= 0) return 0; return weight * 2.5 + 3.99; } What intent and assumption would you document?
Show answer
An intent comment for the formula could be: // Shipping rate: $2.50/lb plus $3.99 flat handling fee (per carrier contract, Jan 2025). This explains where the numbers 2.5 and 3.99 come from and why they were chosen. An assumption comment for the guard clause could be: // Assumes weight is in pounds; a weight of 0 or less means a digital-only order (no shipping). This clarifies the unit of measurement and explains the business logic behind returning 0, preventing a future developer from thinking it's a bug.

Question 3: INTERMEDIATE

The following function has a comment that is technically accurate but poorly written. Rewrite the comment so it explains intent and assumptions instead of narrating the code. // check if score is more than 89 function isHonorRoll(score) { return score > 89; }
Show answer
A better set of comments would be: /** * Determines if a student qualifies for the honor roll. * The threshold of 90+ follows the school's grading policy * (see Student Handbook §4.2). Assumes `score` is a * weighted final percentage (0–100), not a raw point total. * @param {number} score - Weighted final percentage * @returns {boolean} */ function isHonorRoll(score) { return score > 89; } This version explains the intent (school grading policy), states the assumption (score is a weighted percentage, not raw points), and even references where the rule comes from. The original comment 'check if score is more than 89' added nothing that the code didn't already say.

Question 4: APPLIED

You're working on a group project for a game. Your teammate wrote this function but left no comments. There's a bug report that the game freezes when enemies is an empty array. Add comments that would have helped your teammate catch this bug before it shipped. function getStrongestEnemy(enemies) { let strongest = enemies[0]; for (let i = 1; i < enemies.length; i++) { if (enemies[i].hp > strongest.hp) { strongest = enemies[i]; } } return strongest; }
Show answer
The key issue is an unstated assumption: the function assumes enemies has at least one element. When the array is empty, enemies[0] is undefined, and accessing strongest.hp in the loop causes a crash. A proper set of comments would look like: /** * Finds the enemy with the highest HP to target first. * Assumes `enemies` is a non-empty array of objects with * a numeric `hp` property. Returns undefined if array is * empty — callers should check for this. * @param {Array<{hp: number}>} enemies * @returns {Object|undefined} */ function getStrongestEnemy(enemies) { // Guard: avoid crash on empty wave between levels if (enemies.length === 0) return undefined; ... Had the original developer written an assumption comment about needing a non-empty array, the bug would have been caught during code review or testing before it reached players.

Question 5: CRITICAL THINKING

Some developers argue that 'good code doesn't need comments' and that all comments are a sign of failure to write clear code. Others argue that comments are essential for explaining business logic that code cannot express. Take a position and defend it with at least two specific examples from this lesson. Consider: are there situations where comments are irreplaceable? Are there situations where they cause harm?
Show answer
The strongest position is that both views contain truth, but neither is fully correct on its own. Clear, well-named code should be the first line of defense — renaming x to maxRetries is always better than writing a comment explaining what x means. However, code fundamentally cannot express 'why' — for example, the cafeteria function's 40% rate comes from federal NSLP guidelines, and no amount of renaming could embed that context into the code itself. Similarly, the assumption that an array must be sorted can't be communicated through variable names alone. Comments cause harm when they're stale (contradicting code) or narrating (adding noise). They're irreplaceable when documenting business rules, external dependencies, or non-obvious trade-offs. The professional approach is to write clean code first and then add comments specifically where intent and assumptions would otherwise be invisible.

SUMMARY

Lesson Summary

Summary

Effective code comments serve as a bridge between the developer's mind and the reader's understanding. The core skill is learning to explain intent — the why behind a decision, such as a business rule, an algorithm choice, or a performance trade-off — and assumptions — the invisible conditions that must hold true, like input formats, sort orders, or pre-validated data. JavaScript provides single-line comments (//) for brief inline notes, multi-line comments (/* */) for longer explanations, and JSDoc (/** */) for structured documentation that tools can parse automatically.

Remember the two-question framework: before commenting any code, ask "Why did I write it this way?" and "What must be true for this to work?" Avoid narration comments that restate the obvious, and always keep comments up-to-date when code changes. Prefer clear code first and then supplement with comments where the code alone cannot tell the full story. These habits form the foundation of professional software communication and will serve you well from your first group project through your career.

Varsity Tutors • JavaScript • Writing Comments — Write comments that explain intent and assumptions