JavaScript

Lesson 09

Module boundaries and globals

Keep shared behavior behind module APIs instead of scattering mutable global state.

Good Code

review-filters.js
const FILTER_STORAGE_KEY = "review-filters";

export function readReviewFilters(storage) {
  // Storage is a dependency, not hidden global state.
  const rawValue = storage.getItem(FILTER_STORAGE_KEY);

  if (!rawValue) {
    return { status: "open" };
  }

  return JSON.parse(rawValue);
}

export function saveReviewFilters(storage, filters) {
  storage.setItem(FILTER_STORAGE_KEY, JSON.stringify(filters));
}

Bad Code

review-filters.js
window.reviewFilters = { status: "open" };

function readReviewFilters() {
  // Global reads and writes let callers bypass the module API.
  return JSON.parse(localStorage.reviewFilters || "{}");
}

function saveReviewFilters(filters) {
  localStorage.reviewFilters = JSON.stringify(filters);
  window.reviewFilters = filters;
}

Review Notes

What to review

Good Code

The good version hides the storage key inside the module and accepts storage as a dependency, which makes the behavior easier to test and reuse.

Bad Code

The bad version writes to window and localStorage directly from the module, so unrelated code can change state without going through a clear API.

Takeaways

  • Expose small functions from modules and pass dependencies in when code needs storage, network, or browser APIs.