Week 6 - Advanced topics

Synchronous File IO

File processing

Error handling

Array methods

Closures

Style - How to write meaningful comments

Practice

Assignment

Core program

Code Should Speak for Itself

The best code is self-explanatory. Before writing a comment, ask yourself: "Can I make this code clearer instead?”

// Bad: Code needs explanation
const d = u.filter(x => x.a > 18); // get adults

// Good: Code explains itself
const adults = users.filter(user => user.age > 18);

Well-named variables, functions, and clear logic eliminate most needs for comments. If your code requires extensive comments to be understood, it's probably too complex.

<aside> 💡

A good programmer should do everything in their power to make what they write simple for other programmers to use and comprehend.

</aside>

Inline vs Block Comments

JavaScript has two comment styles. Use each appropriately:

Inline Comments (//)

Best for short, single-line explanations:

const TAX_RATE = 0.21; // Dutch VAT rate

// API expects timestamps in seconds, not milliseconds
const timestamp = Date.now() / 1000;

const price = calculatePrice(item); // Includes tax and shipping

Block Comments (/* */)

Best for multi-line explanations or function documentation:

/*
 * This function uses a binary search algorithm for performance.
 * Input array must be sorted in ascending order.
 * Returns -1 if element is not found.
 */
function binarySearch(array, target) {
  // Implementation
}

/*
 * IMPORTANT: Do not modify this regex without testing against:
 * - International phone numbers
 * - Numbers with extensions
 * - Mobile vs landline formats
 */
const phoneRegex = /^\\+?[\\d\\s()-]+$/;

When to use block comments:

When to use inline comments:

Commenting Out Code

// Debugging: temporarily disable validation
// if (!isValid(data)) {
//   throw new Error('Invalid data');
// }

/* 
Keeping this old implementation for reference
function oldApproach() {
  // ...
}
*/

<aside> ⚠️

Don't leave commented-out code in production. Use version control (Git) to track old code instead. Commented code clutters your files and confuses other developers.

</aside>

When to Comment

Comments explain why, not what. Your code already shows what it does: comments should explain the reasoning behind decisions.

// Bad: Explaining what (obvious from code)
// Loop through users
for (const user of users) {
  // Add user to active list
  activeUsers.push(user);
}

// Good: Explaining why (not obvious)
// Cache active users to avoid repeated database queries
const activeUsers = users.filter(user => user.active);

Comment when:

Don't comment when:

Unnecessary Comments vs Good Comments

Unnecessary: Restating Code

// Set name to Alice
const name = 'Alice';

// Check if user is active
if (user.active) {
  // Log message
  console.log('User is active');
}

These comments add no value. You can delete them.

Good Comments

// Use setTimeout to avoid blocking the UI thread during large file processing
setTimeout(() => processLargeFile(data), 0);

// Round to 2 decimals to match accounting requirements
const total = Math.round(price * 100) / 100;

// API returns timestamps in seconds, but JavaScript uses milliseconds
const date = new Date(timestamp * 1000);

These explain decisions that aren't obvious from the code alone.

Function Documentation

For functions that others will use, document the interface:

/**
 * Calculates the discounted price based on user tier
 * 
 * @param {number} price - Original price in euros
 * @param {string} userTier - User membership level ('basic', 'premium', 'vip')
 * @returns {number} Final price after discount
 */
function calculateDiscount(price, userTier) {
  const discounts = { basic: 0, premium: 0.1, vip: 0.2 };
  return price * (1 - discounts[userTier]);
}

Function comment template

/**
 * Brief description of what the function does
 * 
 * @param {type} paramName - What this parameter represents
 * @param {type} paramName2 - What this parameter represents
 * @returns {type} What the function returns
 */

JSDoc

JSDoc is a documentation standard that tools can parse to generate documentation and provide better autocomplete.

/**
 * Creates a new user account
 * 
 * @param {string} username - Unique username (3-20 characters)
 * @param {string} email - Valid email address
 * @param {number} age - User age (must be 18+)
 * @returns {Object} User object with id, username, email, and createdAt
 * @throws {Error} If username is already taken
 */
function createUser(username, email, age) {
  if (existingUsers.includes(username)) {
    throw new Error('Username already exists');
  }
  
  return {
    id: generateId(),
    username,
    email,
    createdAt: new Date()
  };
}

VS Code and other editors use JSDoc to show helpful tooltips when you hover over functions.

Common JSDoc tags:

<aside> 💡

The best documentation is code that doesn't need documentation. Invest time in clear names and simple logic before reaching for comments.

</aside>

Commenting Gotchas and Workarounds

// WORKAROUND: API sometimes returns null instead of empty array
// Remove this once backend issue #247 is fixed
const items = response.data || [];

// NOTE: Must use var here due to hoisting requirements in legacy code
// TODO: Refactor to let once module system is updated
var globalConfig = loadConfig();

// HACK: Waiting 100ms for DOM to update
// Better solution needed - investigate MutationObserver
setTimeout(() => updateUI(), 100);

Use keywords like WORKAROUND, HACK, TODO, FIXME, NOTE to flag temporary solutions or future improvements.

When Code is Complex

Sometimes complexity is unavoidable. In these cases, explain the approach:

/**
 * Implements the Collatz conjecture sequence
 * See: <https://en.wikipedia.org/wiki/Collatz_conjecture>
 * 
 * For any positive integer n:
 * - If n is even: divide by 2
 * - If n is odd: multiply by 3 and add 1
 * - Repeat until reaching 1
 */
function collatz(n) {
  const sequence = [n];
  
  while (n !== 1) {
    n = n % 2 === 0 ? n / 2 : 3 * n + 1;
    sequence.push(n);
  }
  
  return sequence;
}

Summary

Good commenting principles:

Before commenting, ask:

  1. Can I rename variables/functions to make this clearer?
  2. Can I simplify the logic?
  3. Am I explaining why, not what?
  4. Will this comment still be accurate in 6 months?

Additional Resources

Reading: