← Назад к вопросам
Что такое процедурное программирование?
1.3 Junior🔥 201 комментариев
#Архитектура и паттерны
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Процедурное программирование
Процедурное программирование — это парадигма, где программа состоит из последовательности процедур (функций), которые изменяют состояние данных. Это один из основных подходов в программировании, особенно популярный в старых языках.
Основные принципы
1. Программа как последовательность команд:
// Процедурное программирование - команда за командой
let balance = 1000;
let interest = 0.05;
function addInterest() {
balance = balance + (balance * interest);
}
function withdraw(amount) {
if (amount <= balance) {
balance = balance - amount;
}
}
function deposit(amount) {
balance = balance + amount;
}
addInterest();
withdraw(100);
deposit(50);
2. Состояние изменяется явно:
// Переменные глобального состояния
let count = 0;
let messages = [];
let isLoading = false;
// Функции изменяют это состояние
function increment() {
count = count + 1; // Явное изменение
}
function addMessage(msg) {
messages.push(msg); // Изменение массива
}
function startLoading() {
isLoading = true; // Изменение флага
}
3. Сосредоточенность на «как» делать:
// Процедурное: ШАГ ЗА ШАГОМ
function calculateTotal(prices) {
let total = 0;
for (let i = 0; i < prices.length; i++) {
total = total + prices[i]; // Шаг 1: перебрать
} // Шаг 2: суммировать
return total;
}
// vs Функциональное (декларативное): ЧТО мы хотим
const calculateTotal = (prices) => prices.reduce((sum, price) => sum + price, 0);
Реальный пример: простой счётчик
// Процедурное программирование
let count = 0; // Глобальное состояние
function increment() {
count = count + 1;
updateDisplay();
}
function decrement() {
count = count - 1;
updateDisplay();
}
function reset() {
count = 0; // Явно устанавливаем значение
updateDisplay();
}
function updateDisplay() {
document.getElementById('counter').textContent = count;
}
// Использование
increment(); // count = 1
increment(); // count = 2
decrement(); // count = 1
reset(); // count = 0
Минусы процедурного подхода
1. Глобальное состояние (Spaghetti Code):
// Плохо - состояние везде, сложно отследить
let user = null;
let isAuthenticated = false;
let token = null;
let cart = [];
let isLoading = false;
function login(email, password) {
isLoading = true;
fetchUser(email, password).then((data) => {
user = data.user; // Изменяем глобальное состояние
isAuthenticated = true; // Глобальное состояние
token = data.token; // Глобальное состояние
isLoading = false; // Глобальное состояние
});
}
function addToCart(item) {
if (!isAuthenticated) { // Зависит от глобального состояния
return;
}
cart.push(item); // Изменяем глобальное состояние
}
2. Сложно тестировать:
// Процедурное - нужно мокировать всё
let globalData = { count: 0 };
function increment() {
globalData.count++; // Зависит от глобального состояния
}
// Тест - нужно сбрасывать состояние
beforeEach(() => {
globalData = { count: 0 }; // Очистка
});
test('increment', () => {
increment();
expect(globalData.count).toBe(1);
});
3. Побочные эффекты везде:
// Процедурное - побочные эффекты
let results = [];
function process(items) {
results = []; // Модифицирует внешнее состояние
for (let item of items) {
const processed = item * 2;
results.push(processed); // Побочный эффект
console.log(processed); // Побочный эффект
}
return results; // Но также возвращает значение
}
Процедурное vs Объектное vs Функциональное
// === ПРОЦЕДУРНОЕ ===
let balance = 100;
function withdraw(amount) {
balance -= amount; // Изменяет внешнее состояние
}
// === ОБЪЕКТНОЕ (ООП) ===
class Account {
constructor(initialBalance) {
this.balance = initialBalance; // Состояние в объекте
}
withdraw(amount) {
this.balance -= amount; // Изменяет состояние объекта
}
}
// === ФУНКЦИОНАЛЬНОЕ ===
function withdraw(account, amount) {
return {
...account,
balance: account.balance - amount // Создаёт новый объект
};
}
// Использование
const newAccount = withdraw(account, 50); // Не изменяет оригинальный
Когда процедурное программирование ХОРОШО
// 1. Простые скрипты
function generateReport() {
const data = loadData();
const processed = processData(data);
const sorted = sortData(processed);
displayReport(sorted);
}
// 2. Пошаговые алгоритмы
function bubbleSort(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length - 1; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
}
}
}
return arr;
}
// 3. Скрипты для обработки данных
function processCSV(data) {
const lines = data.split('\n');
const result = [];
for (let line of lines) {
const values = line.split(',');
result.push({ name: values[0], age: values[1] });
}
return result;
}
Процедурное программирование в контексте Frontend
// jQuery эпоха - процедурное программирование
$(document).ready(function() {
let todos = [];
$('#add-btn').click(function() {
const text = $('#input').val();
todos.push({ id: Date.now(), text: text, done: false });
$('#input').val('');
renderTodos(); // Пересчитываем весь список
});
function renderTodos() {
$('#list').empty(); // Очищаем
todos.forEach(function(todo) {
const li = '<li>' + todo.text + '</li>';
$('#list').append(li); // Добавляем
});
}
});
// vs Современный React (декларативный)
function TodoApp() {
const [todos, setTodos] = useState([]);
return (
<div>
<input
onChange={(e) => {
// Не вызываем функции, просто описываем как должно выглядеть
}}
/>
<ul>
{todos.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
</div>
);
}
Проблемы в больших приложениях
// Процедурное программирование становится ужасным когда много кода
let globalState = {
user: null,
cart: [],
notifications: [],
isLoading: false,
// ... ещё 20 переменных
};
function updateUser() { /* ... */ }
function addToCart() { /* ... */ }
function removeFromCart() { /* ... */ }
function checkout() { /* ... */ }
function login() { /* ... */ }
// ... ещё 30 функций, всё модифицирует globalState
// РЕЗУЛЬТАТ: Impossible to debug, hard to test, spaghetti code
Вывод
Процедурное программирование:
- Программа = последовательность команд
- Состояние хранится в переменных
- Функции изменяют это состояние
- Подходит для простых скриптов
- Плохо масштабируется на больших приложениях
В Frontend:
- jQuery эра — процедурное программирование
- React/Vue era — функциональное/компонентное (лучше)
- Всё же процедурный код работает везде (старые браузеры, простые скрипты)
Современный подход:
- Избегай глобального состояния
- Используй React/Vue для управления состоянием
- Функции без побочных эффектов где возможно
- Тестируй компоненты, не глобальные переменные