Читаемость кода - это не “красота”, а снижение количества ошибок и упрощение поддержки. Несколько простых правил дают заметный эффект даже в небольших проектах.
1) Имена должны объяснять смысл
Хорошее имя отвечает на вопрос “что это такое” или “что делает”.
Плохо:
function f(a, b) {
return a - (a * b) / 100;
}
Лучше:
function calcDiscountedPrice(price, percent) {
return price - (price * percent) / 100;
}
Для переменных: что хранится
Плохо:
const x = 10;
const y = 3;
Лучше:
const totalItems = 10;
const visibleItems = 3;
Для функций: что возвращается или что делает
Обычно функции называют глаголом:
get...,create...,build...,calc...,format...,parse...,is...,has...
Примеры:
function getUserName(user) {
return user.name;
}
function isAdult(age) {
return age >= 18;
}
2) Маленькие функции лучше больших
Функция обычно понятнее, если она:
- делает одну вещь;
- легко описывается одной фразой;
- не требует держать в голове много деталей.
Плохой пример (слишком много задач в одной функции):
function handle(input) {
const text = String(input).trim().toLowerCase();
const n = Number(text);
if (Number.isNaN(n)) return null;
if (n < 0) return null;
return n * 2;
}
Лучше разбить на шаги:
function normalizeText(input) {
return String(input).trim().toLowerCase();
}
function parseNonNegativeNumber(value) {
const n = Number(value);
if (Number.isNaN(n)) return null;
if (n < 0) return null;
return n;
}
function doubleNonNegative(input) {
const text = normalizeText(input);
const n = parseNonNegativeNumber(text);
if (n === null) return null;
return n * 2;
}
console.log(doubleNonNegative(" 5 ")); // 10
3) Guard clauses уменьшают вложенность
Чем меньше уровней вложенности, тем легче читать.
Менее удачно:
function formatName(user) {
if (user) {
if (user.name) {
return user.name.trim();
} else {
return "Unknown";
}
} else {
return "Unknown";
}
}
Читабельнее:
function formatName(user) {
if (!user) return "Unknown";
if (!user.name) return "Unknown";
return user.name.trim();
}
4) Условия должны быть короткими и точными
Если условие стало длинным, его проще вынести в переменную с хорошим именем.
const user = { isActive: true, role: "editor", isBanned: false };
const canEdit = user.isActive && user.role === "editor" && !user.isBanned;
if (canEdit) {
console.log("edit allowed");
}
Если условие сложно назвать, это сигнал, что логика может быть слишком плотной для одного места.
5) Магические числа и строки лучше выносить в константы
Когда в коде встречается “42” или “admin” без контекста, читателю приходится гадать, что это значит.
const MAX_RETRIES = 3;
const ADMIN_ROLE = "admin";
function canAccess(user) {
if (!user) return false;
if (user.role !== ADMIN_ROLE) return false;
return true;
}
function retry(fn) {
for (let i = 0; i < MAX_RETRIES; i += 1) {
const result = fn();
if (result) return result;
}
return null;
}
6) Один стиль - меньше сюрпризов
Даже хороший код становится тяжелее, если в одном файле смешаны разные стили. Практичные правила для старта:
- придерживаться одного способа именования (например,
camelCase) - одинаково форматировать условия и циклы
- не смешивать
varсlet/const - не менять стиль кавычек в пределах проекта
7) Комментарии - не вместо понятного кода
Комментарий полезен, когда он объясняет “почему”, а не “что делает эта строка”. Если приходится объяснять очевидное, чаще помогает переименование или вынос в функцию.
Менее удачно:
function calc(a, b) {
return a + b; // складывает a и b
}
Лучше:
function sum(a, b) {
return a + b;
}
Небольшой чеклист
- имя переменной отвечает на вопрос “что хранится”
- имя функции отвечает на вопрос “что делает” или “что возвращает”
- функция делает одну вещь
- вложенность минимальна (guard clauses помогают)
- условия читаются и при необходимости выносятся в переменные
- “магические” значения оформлены как константы
Что стоит запомнить
- Читаемость - это уменьшение ошибок и ускорение работы с кодом.
- Хорошие имена и маленькие функции дают самый быстрый эффект.
- Guard clauses и короткие условия делают логику прямой и понятной.
- Константы убирают “магические” значения.