← Назад к вопросам

Приведи примеры задач которые делаешь на JavaScript

2.0 Middle🔥 301 комментариев
#JavaScript Core#Soft Skills и рабочие процессы

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Примеры типовых задач на JavaScript в Frontend-разработке

Как Frontend Developer с 10+ лет опыта, я решаю широкий спектр задач — от простой манипуляции DOM до создания сложных SPA-приложений. Вот ключевые категории с примерами:

1. Манипуляция DOM и работа с событиями

Цель: Динамическое изменение контента и обработка пользовательских взаимодействий.

// Пример: Создание интерактивного списка задач (To-Do)
class TodoList {
    constructor(containerId) {
        this.container = document.getElementById(containerId);
        this.tasks = [];
        this.init();
    }

    init() {
        this.renderForm();
        this.container.addEventListener('click', (e) => {
            if (e.target.classList.contains('delete-btn')) {
                this.deleteTask(e.target.dataset.id);
            }
        });
    }

    renderForm() {
        const form = document.createElement('form');
        form.innerHTML = `
            <input type="text" class="task-input" placeholder="Новая задача">
            <button type="submit">Добавить</button>
        `;
        form.addEventListener('submit', (e) => {
            e.preventDefault();
            const input = form.querySelector('.task-input');
            if (input.value.trim()) {
                this.addTask(input.value.trim());
                input.value = '';
            }
        });
        this.container.appendChild(form);
    }

    addTask(text) {
        const task = { id: Date.now(), text, completed: false };
        this.tasks.push(task);
        this.renderTasks();
    }

    deleteTask(id) {
        this.tasks = this.tasks.filter(task => task.id !== Number(id));
        this.renderTasks();
    }

    renderTasks() {
        const list = this.container.querySelector('.task-list') || document.createElement('ul');
        list.className = 'task-list';
        list.innerHTML = this.tasks.map(task => `
            <li>
                ${task.text}
                <button class="delete-btn" data-id="${task.id}">Удалить</button>
            </li>
        `).join('');
        if (!this.container.querySelector('.task-list')) {
            this.container.appendChild(list);
        }
    }
}

// Использование
new TodoList('todo-container');

2. Работа с API и асинхронными операциями

Цель: Получение, отправка данных и обработка асинхронных сценариев.

// Пример: Загрузка и отображение данных с внешнего API
async function loadUserData(userId) {
    try {
        // Используем Promise.all для параллельных запросов
        const [userResponse, postsResponse] = await Promise.all([
            fetch(`https://jsonplaceholder.typicode.com/users/${userId}`),
            fetch(`https://jsonplaceholder.typicode.com/users/${userId}/posts`)
        ]);

        if (!userResponse.ok || !postsResponse.ok) {
            throw new Error('Ошибка загрузки данных');
        }

        const user = await userResponse.json();
        const posts = await postsResponse.json();

        return { user, posts };
    } catch (error) {
        console.error('Произошла ошибка:', error);
        // Можно добавить повторные попытки или fallback-логику
        return { user: null, posts: [], error: error.message };
    }
}

// Использование с современным синтаксисом
const displayData = async (userId) => {
    const { user, posts, error } = await loadUserData(userId);
    
    if (error) {
        document.getElementById('content').innerHTML = `
            <div class="error">Ошибка: ${error}</div>
        `;
        return;
    }

    document.getElementById('content').innerHTML = `
        <h2>${user.name}</h2>
        <p>Email: ${user.email}</p>
        <h3>Посты (${posts.length}):</h3>
        <ul>
            ${posts.map(post => `<li><strong>${post.title}</strong>: ${post.body}</li>`).join('')}
        </ul>
    `;
};

// Пример с debounce для поиска
function createSearchInput(apiEndpoint) {
    let timeoutId;
    const searchInput = document.getElementById('search');
    
    searchInput.addEventListener('input', (e) => {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(async () => {
            const results = await searchData(apiEndpoint, e.target.value);
            updateResultsUI(results);
        }, 300); // Задержка 300мс
    });
}

3. Состояние приложения и управление данными

Цель: Создание предсказуемого состояния в сложных интерфейсах.

// Пример: Простой менеджер состояния (State Manager)
class StateManager {
    constructor(initialState = {}) {
        this.state = initialState;
        this.listeners = [];
        this.actions = {};
    }

    subscribe(listener) {
        this.listeners.push(listener);
        return () => {
            this.listeners = this.listeners.filter(l => l !== listener);
        };
    }

    setState(newState) {
        this.state = { ...this.state, ...newState };
        this.notifyListeners();
    }

    notifyListeners() {
        this.listeners.forEach(listener => listener(this.state));
    }

    registerAction(name, action) {
        this.actions[name] = (payload) => {
            const newState = action(this.state, payload);
            this.setState(newState);
        };
    }

    dispatch(actionName, payload) {
        if (this.actions[actionName]) {
            this.actions[actionName](payload);
        }
    }
}

// Использование
const store = new StateManager({
    user: null,
    cart: [],
    isAuthenticated: false
});

// Регистрируем actions
store.registerAction('ADD_TO_CART', (state, product) => ({
    ...state,
    cart: [...state.cart, product]
}));

store.registerAction('LOGIN', (state, user) => ({
    ...state,
    user,
    isAuthenticated: true
}));

// Подписываемся на изменения
const unsubscribe = store.subscribe((state) => {
    console.log('Состояние обновлено:', state);
    updateUI(state);
});

// Диспатчим actions
store.dispatch('LOGIN', { name: 'Иван', email: 'ivan@example.com' });
store.dispatch('ADD_TO_CART', { id: 1, name: 'Ноутбук', price: 999 });

4. Оптимизация производительности

Цель: Улучшение скорости загрузки и отзывчивости интерфейса.

// Пример: Ленивая загрузка изображений (Lazy Loading)
class LazyLoader {
    constructor() {
        this.images = document.querySelectorAll('img[data-src]');
        this.observer = null;
        this.init();
    }

    init() {
        if ('IntersectionObserver' in window) {
            this.observer = new IntersectionObserver((entries) => {
                entries.forEach(entry => {
                    if (entry.isIntersecting) {
                        this.loadImage(entry.target);
                        this.observer.unobserve(entry.target);
                    }
                });
            }, {
                rootMargin: '50px 0px',
                threshold: 0.01
            });

            this.images.forEach(img => this.observer.observe(img));
        } else {
            // Fallback для старых браузеров
            this.loadImagesFallback();
        }
    }

    loadImage(img) {
        img.src = img.dataset.src;
        img.onload = () => {
            img.removeAttribute('data-src');
            img.classList.add('loaded');
        };
    }

    loadImagesFallback() {
        this.images.forEach(img => {
            if (this.isInViewport(img)) {
                this.loadImage(img);
            }
        });
        
        // Дебаунс для scroll события
        let scrollTimeout;
        window.addEventListener('scroll', () => {
            clearTimeout(scrollTimeout);
            scrollTimeout = setTimeout(() => {
                this.images.forEach(img => {
                    if (img.hasAttribute('data-src') && this.isInViewport(img)) {
                        this.loadImage(img);
                    }
                });
            }, 100);
        });
    }

    isInViewport(element) {
        const rect = element.getBoundingClientRect();
        return (
            rect.top >= 0 &&
            rect.left >= 0 &&
            rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
            rect.right <= (window.innerWidth || document.documentElement.clientWidth)
        );
    }
}

// Инициализация при загрузке страницы
document.addEventListener('DOMContentLoaded', () => new LazyLoader());

5. Работа с формами и валидация

Цель: Создание удобных, безопасных и отзывчивых форм.

// Пример: Комплексная валидация формы
class FormValidator {
    constructor(formId, config) {
        this.form = document.getElementById(formId);
        this.config = config;
        this.errors = new Set();
        this.init();
    }

    init() {
        this.form.addEventListener('submit', (e) => this.handleSubmit(e));
        
        // Валидация в реальном времени
        Object.keys(this.config.fields).forEach(fieldName => {
            const field = this.form.querySelector(`[name="${fieldName}"]`);
            if (field) {
                field.addEventListener('blur', () => this.validateField(fieldName));
                field.addEventListener('input', () => {
                    if (this.errors.has(fieldName)) {
                        this.validateField(fieldName);
                    }
                });
            }
        });
    }

    validateField(fieldName) {
        const field = this.form.querySelector(`[name="${fieldName}"]`);
        const rules = this.config.fields[fieldName];
        const value = field.value.trim();
        const errorElement = this.getErrorElement(field);
        
        // Очищаем предыдущие ошибки
        this.clearFieldError(fieldName);
        
        for (const rule of rules) {
            const isValid = this.checkRule(rule, value);
            
            if (!isValid) {
                this.errors.add(fieldName);
                this.showError(field, errorElement, rule.message);
                return false;
            }
        }
        
        this.errors.delete(fieldName);
        this.showSuccess(field, errorElement);
        return true;
    }

    checkRule(rule, value) {
        switch (rule.type) {
            case 'required':
                return value.length > 0;
            case 'minLength':
                return value.length >= rule.value;
            case 'maxLength':
                return value.length <= rule.value;
            case 'pattern':
                return rule.value.test(value);
            case 'custom':
                return rule.validate(value);
            default:
                return true;
        }
    }

    handleSubmit(e) {
        e.preventDefault();
        
        // Валидируем все поля
        let isValid = true;
        Object.keys(this.config.fields).forEach(fieldName => {
            if (!this.validateField(fieldName)) {
                isValid = false;
            }
        });
        
        if (isValid) {
            const formData = new FormData(this.form);
            const data = Object.fromEntries(formData);
            this.config.onSuccess(data);
        } else {
            this.config.onError?.(Array.from(this.errors));
        }
    }

    getErrorElement(field) {
        let errorElement = field.parentElement.querySelector('.error-message');
        if (!errorElement) {
            errorElement = document.createElement('div');
            errorElement.className = 'error-message';
            field.parentElement.appendChild(errorElement);
        }
        return errorElement;
    }

    clearFieldError(fieldName) {
        const field = this.form.querySelector(`[name="${fieldName}"]`);
        const errorElement = field.parentElement.querySelector('.error-message');
        if (errorElement) {
            errorElement.textContent = '';
            errorElement.classList.remove('active');
        }
        field.classList.remove('error', 'success');
    }

    showError(field, errorElement, message) {
        errorElement.textContent = message;
        errorElement.classList.add('active');
        field.classList.add('error');
        field.classList.remove('success');
    }

    showSuccess(field, errorElement) {
        errorElement.textContent = '';
        errorElement.classList.remove('active');
        field.classList.remove('error');
        field.classList.add('success');
    }
}

// Конфигурация валидации
const registrationConfig = {
    fields: {
        email: [
            { type: 'required', message: 'Email обязателен' },
            { type: 'pattern', value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, message: 'Неверный формат email' }
        ],
        password: [
            { type: 'required', message: 'Пароль обязателен' },
            { type: 'minLength', value: 8, message: 'Минимум 8 символов' },
            { 
                type: 'custom', 
                message: 'Пароль должен содержать цифры и буквы',
                validate: (value) => /\d/.test(value) && /[a-zA-Z]/.test(value)
            }
        ]
    },
    onSuccess: (data) => {
        console.log('Форма валидна, данные:', data);
        // Отправка на сервер
    },
    onError: (errors) => {
        console.log('Ошибки в полях:', errors);
    }
};

// Использование
new FormValidator('registration-form', registrationConfig);

Другие распространенные задачи:

  • Роутинг в SPA: Реализация клиентского роутинга с History API
  • Веб-компоненты: Создание переиспользуемых компонентов с Custom Elements
  • Графики и визуализация: Работа с Canvas, SVG и библиотеками типа D3.js
  • PWA-функционал: Service Workers, кеширование, офлайн-работа
  • Интернационализация: Поддержка multiple языков и форматов
  • Тестирование: Написание unit- и e2e-тестов (Jest, Cypress)
  • Бандлинг и оптимизация: Настройка Webpack/Vite, code splitting, tree shaking

Каждая задача требует не только знания синтаксиса JavaScript, но и понимания архитектурных паттернов (MVC, Flux, Observer), принципов чистого кода и оптимизации производительности. Современный Frontend Developer должен уметь выбирать правильные подходы в зависимости от масштаба проекта и требований к производительности.