Изучаем JavaScript на примерах: от циклов до обработки ошибок

Раздел: JavaScript -> Основы языка JavaScript

Основные примеры кода на JavaScript

В этом разделе рассматриваются часто встречающиеся задачи при написании кода на JavaScript. Для каждой задачи приведено основное эффективное решение, а также альтернативные варианты с указанием целей и возможных проблем.

Как перебрать массив?

Цель: последовательно обработать каждый элемент массива. Основной метод – forEach.

Решение с использованием forEach:


const numbers = [1, 2, 3, 4, 5];
numbers.forEach(function(element, index) {
  console.log(`Элемент ${index}: ${element}`);
});

Find js (поиск в javascript)

Метод forEach выполняет переданную функцию для каждого элемента массива. Первый аргумент – текущий элемент, второй – индекс. Этот способ удобен для побочных эффектов, не создаёт новый массив.

Как использовать классический цикл for?


for (let i = 0; i < numbers.length; i++) {
  console.log(numbers[i]);
}

Js примеры (примеры кода на javascript)

Цикл for даёт полный контроль над индексом и условием остановки. Применяется, когда требуется прервать цикл (break) или пропустить итерацию (continue).

Как применить for...of для простого перебора значений?


for (const value of numbers) {
  console.log(value);
}

Javascript строки (строки в javascript)

Конструкция for...of перебирает значения итерируемых объектов (массивы, строки, Map, Set). Код более лаконичен, но не предоставляет индекс напрямую.

Как создать новый массив на основе существующего с помощью map?


const doubled = numbers.map(x => x * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

Js фильтр (фильтрация в javascript)

Метод map возвращает новый массив той же длины, где каждый элемент преобразован согласно функции. Идеален для трансформации данных без мутации исходного массива.

Возможные проблемы:

  • В forEach нельзя использовать break или continue. Для досрочного выхода требуется цикл for или some/every.
  • В старых браузерах forEach может отсутствовать (полифилл).
  • При передаче функции с контекстом (например, метод объекта) теряется привязка this. Решение – использовать стрелочную функцию или bind.
  • Цикл for с var создаёт глобальную переменную, лучше применять let.

Как объявить и вызвать функцию?

Цель: определить блок кода, который можно многократно выполнять с разными аргументами. Основной способ – function declaration.


function greet(name) {
  return `Привет, ${name}!`;
}
console.log(greet('Анна')); // Привет, Анна!

Javascript переменные (переменные в javascript)

Объявление функции через function всплывает (hoisting), поэтому её можно вызвать до объявления. Подходит для всех сценариев.

Как использовать function expression?


const greetExpr = function(name) {
  return `Привет, ${name}!`;
};
console.log(greetExpr('Пётр'));

Meta js (мета-теги в javascript)

Функциональное выражение присваивается переменной. Не всплывает, поэтому вызывать можно только после объявления. Удобно для анонимных функций.

Когда применяется стрелочная функция (arrow function)?


const greetArrow = (name) => `Привет, ${name}!`;
console.log(greetArrow('Мария'));

Href javascript (ссылки javascript)

Стрелочные функции не имеют собственного this и arguments. Они наследуют контекст из внешней области. Компактны, особенно для коротких операций.

Возможные проблемы:

  • Стрелочные функции не подходят для методов объекта, если требуется доступ к this объекта.
  • function declaration может быть переопределена, что иногда приводит к путанице.
  • При использовании function expression без имени (анонимная) стек вызовов менее информативен при отладке.

Как работать со свойствами объекта?

Цель: хранить и извлекать данные в формате ключ-значение. Базовый способ – точечная нотация.


const user = { name: 'Иван', age: 30 };
console.log(user.name); // Иван
user.age = 31;

Js приложения (приложения на javascript)

Точечная нотация проста и читаема. Подходит для статически известных имён свойств.

Как использовать квадратные скобки для динамических ключей?


const key = 'name';
console.log(user[key]); // Иван
user['newKey'] = 'value';

Квадратные скобки позволяют обращаться к свойствам через строку или переменную. Обязательны, если имя свойства содержит пробелы или начинается с цифры.

Как скопировать или объединить объекты?


const clone = Object.assign({}, user);
const merged = { ...user, age: 32 };

Object.assign и оператор расширения (spread) создают поверхностную копию. Полезны для обновления состояния без мутации.

Возможные проблемы:

  • Поверхностное копирование не затрагивает вложенные объекты (глубокое копирование требует дополнительных действий).
  • Оператор spread не копирует методы прототипа.
  • Обращение к несуществующему свойству возвращает undefined, что может привести к скрытым ошибкам.

Как обработать ошибку в JavaScript?

Цель: корректно реагировать на исключительные ситуации. Основная конструкция – try...catch.


try {
  const result = JSON.parse('некорректный JSON');
} catch (error) {
  console.error('Ошибка парсинга:', error.message);
}

Блок try содержит код, который может выбросить исключение. Если ошибка возникает, управление переходит в catch, где её можно обработать.

Как использовать блок finally?


try {
  // код
} catch (e) {
  // обработка
} finally {
  console.log('Это выполняется всегда');
}

finally выполняется в любом случае (даже если в try был return). Подходит для освобождения ресурсов (закрытие файлов, очистка таймеров).

Как выбросить собственную ошибку?


function divide(a, b) {
  if (b === 0) {
    throw new Error('Деление на ноль');
  }
  return a / b;
}

С помощью throw можно создавать пользовательские ошибки, используя встроенный класс Error или его подклассы.

Возможные проблемы:

  • Слишком широкий catch (без проверки типа ошибки) может скрыть программные ошибки.
  • Блок finally не предотвращает распространение ошибки, если он не содержит return или другой выброс.
  • При асинхронных операциях (промисы, async/await) конструкция try...catch работает только с await.

Расширенные примеры использования

Пример 1: reduce для вычисления сводной статистики

Метод reduce позволяет свернуть массив в одно значение, но его можно применять и для более сложных агрегаций.

Пример

const purchases = [
  { product: 'Книга', price: 500, quantity: 2 },
  { product: 'Тетрадь', price: 50, quantity: 10 },
  { product: 'Ручка', price: 30, quantity: 5 }
];
const totalCost = purchases.reduce((acc, item) => {
  return acc + item.price * item.quantity;
}, 0);
console.log('Общая стоимость:', totalCost);
Общая стоимость: 1650

Пример 2: Замыкание для создания счётчика с приватным состоянием

Замыкания сохраняют доступ к переменным внешней функции даже после её завершения. Это основа для инкапсуляции.

Пример

function createCounter(start = 0) {
  let count = start;
  return {
    increment() { return ++count; },
    decrement() { return --count; },
    reset() { count = start; return count; }
  };
}
const counter = createCounter(10);
console.log(counter.increment()); // 11
console.log(counter.decrement()); // 10
console.log(counter.reset());     // 10
11
10
10

Пример 3: Proxy для валидации свойств объекта

Объект Proxy перехватывает операции над объектом. Можно, например, проверять тип присваиваемого значения.

Пример

const validator = {
  set(target, property, value) {
    if (property === 'age' && (typeof value !== 'number' || value < 0)) {
      throw new TypeError('Возраст должен быть неотрицательным числом');
    }
    target[property] = value;
    return true;
  }
};
const person = new Proxy({}, validator);
person.name = 'Алексей';
person.age = 25;
console.log(person.age); // 25
// person.age = -5; // Выбросит TypeError
25

Пример 4: Обработка ошибок в асинхронных функциях с async/await

При работе с промисами блок try...catch корректно ловит ошибки, выброшенные внутри async функции.

Пример

async function fetchUserData(userId) {
  try {
    const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const user = await response.json();
    console.log('Имя пользователя:', user.name);
  } catch (error) {
    console.error('Не удалось загрузить данные:', error.message);
  }
}
fetchUserData(1);
Имя пользователя: Leanne Graham

В реальном приложении вместо console.log данные отображаются в интерфейсе.

Пример 5: Генератор для бесконечной последовательности

Генераторы позволяют приостанавливать и возобновлять выполнение, возвращая последовательность значений по требованию.

Пример

function* fibonacci() {
  let a = 0, b = 1;
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}
const fib = fibonacci();
console.log(fib.next().value); // 0
console.log(fib.next().value); // 1
console.log(fib.next().value); // 1
console.log(fib.next().value); // 2
console.log(fib.next().value); // 3
0
1
1
2
3

Примеры кода на JavaScript - comments

En
Js примеры (javascript)