Clean Code in JavaScript: Principles and Practical Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Clean Code in JavaScript: Principles and Practical Examples

\n\n

Clean Code is not just a trendy term, but a development philosophy that transforms a chaotic set of instructions into a coherent, readable, and maintainable system. In the world of JavaScript and Node.js, where projects grow and become more complex quickly, the ability to write clean code becomes a critically important skill. In this article, we will break down the key principles of Clean Code using concrete examples with Node.js.

\n\n

Why is Clean Code Important for a JavaScript Developer?

\n\n

JavaScript is a dynamically typed and highly flexible language, which is both its strength and a source of problems. Without adhering to clean code disciplines, a project quickly turns into a "swamp" where any change can break unexpected parts of the system. Clean Code helps to:

\n
    \n
  • Reduce the number of bugs and the time spent finding them.
  • \n
  • Speed up the onboarding of new developers to the project.
  • \n
  • Facilitate refactoring and scaling of the codebase.
  • \n
  • Improve the quality of code reviews.
  • \n
\n\n

Principle 1: Meaningful Names — The Foundation of Understanding

\n\n

The first and most important principle of Clean Code is correctly naming variables, functions, classes, and files. The name should answer the questions "what is this?" and "what is it for?". Avoid single-letter variables (except for loop counters) and abstract names.

\n\n

Bad Example (Node.js):

\n
// What does this function do? Unclear.\nfunction d(a, b) {\n  let r = [];\n  for (let i = 0; i < a.length; i++) {\n    if (b.includes(a[i])) {\n      r.push(a[i]);\n    }\n  }\n  return r;\n}\n\n// Usage\nconst arr1 = [1, 2, 3, 4, 5];\nconst arr2 = [3, 4, 5, 6, 7];\nconst result = d(arr1, arr2);\nconsole.log(result); // [3, 4, 5]
\n\n

Good Example (Clean Code):

\n
// The function and parameter names speak for themselves\nfunction findCommonElements(array1, array2) {\n  const commonElements = [];\n  for (const element of array1) {\n    if (array2.includes(element)) {\n      commonElements.push(element);\n    }\n  }\n  return commonElements;\n}\n\n// Usage\nconst firstList = [1, 2, 3, 4, 5];\nconst secondList = [3, 4, 5, 6, 7];\nconst intersection = findCommonElements(firstList, secondList);\nconsole.log(intersection); // [3, 4, 5]
\n\n

Additional Naming Recommendations:

\n
    \n
  • Boolean variables: use prefixes is, has, can (e.g., isActive, hasPermission).
  • \n
  • Functions: use verbs (getUserData, validateEmail, sendNotification).
  • \n
  • Constants: write in UPPER_SNAKE_CASE (MAX_RETRY_COUNT, DEFAULT_TIMEOUT_MS).
  • \n
\n\n

Principle 2: Small Functions with a Single Responsibility

\n\n

Each function should do only one thing and do it well. If a function performs several actions (e.g., validates data, makes a database request, and sends an email), it should be broken down into several small functions. This improves testability and code reusability.

\n\n

Bad Example (Node.js Express):

\n
app.post('/api/users', async (req, res) => {\n  const { name, email, password } = req.body;\n\n  // Validation\n  if (!name || !email || !password) {\n    return res.status(400).json({ error: 'Missing fields' });\n  }\n  if (password.length < 8) {\n    return res.status(400).json({ error: 'Password too short' });\n  }\n\n  // Database work\n  const existingUser = await db.findUserByEmail(email);\n  if (existingUser) {\n    return res.status(409).json({ error: 'User exists' });\n  }\n\n  const hashedPassword = await bcrypt.hash(password, 10);\n  const newUser = await db.createUser({ name, email, password: hashedPassword });\n\n  //                

Blogs

Book Recommendations