5 фатальных ошибок JavaScript новичков (и как их избежать)

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Почему JavaScript ломает мозг, но не должен ломать карьеру

JavaScript — это одновременно и самый дружелюбный, и самый коварный язык программирования. С одной стороны, вы пишете console.log('Hello') — и в браузере тут же появляется результат. С другой — этот же код может внезапно выдать undefined, NaN или что-то похуже, и вы будете час искать ошибку, которая прячется в одной строчке.

На pythonlib.ru мы знаем, как важно учиться на чужих граблях. В этой статье разберём 5 типичных ошибок новичков в JavaScript, которые превращают код в тыкву. И главное — покажем, как их исправить. Поехали!

Ошибка №1: Волшебное «var» и непонимание области видимости

Многие начинающие разработчики, которые изучают JavaScript, используют var для объявления переменных. Это наследие старого стандарта ES5, которое до сих пор живёт в учебниках десятилетней давности. Но var — это как старая машина без подушек безопасности: ехать можно, но при первой же аварии (читай: баге) вы сильно пострадаете.

В чём проблема?

var имеет функциональную область видимости, а не блочную. Это значит, что переменная, объявленная внутри if или for, будет доступна за их пределами.

// Пример: Ошибка с var
function testVar() {
  if (true) {
    var x = 10;
  }
  console.log(x); // 10 — работает, хотя x объявлен внутри if
}

testVar();

Теперь представьте, что у вас в проекте 1000 строк кода. Вы объявили var i в цикле, а позже случайно используете ту же переменную — получаете баг, который невозможно отследить.

Как правильно?

Используйте let и const. Они имеют блочную область видимости и ведут себя предсказуемо.

// Правильно: let и const
function testLet() {
  if (true) {
    let y = 20;
    const z = 30;
  }
  console.log(y); // ReferenceError: y is not defined
}

testLet();

Совет: всегда используйте const по умолчанию. Только если переменная будет переприсваиваться — берите let. var оставьте в прошлом, как дискеты.

Ошибка №2: Забытый ключ «this» — контекст, который теряется

Ключевое слово this в JavaScript — это как сюрприз в шоколадном яйце: никогда не знаешь, что выпадет. Новички часто думают, что this всегда указывает на текущий объект. Но это не так. this зависит от того, как вызвана функция, а не где она объявлена.

Классический пример: потеря контекста в колбэке

const user = {
  name: 'Анна',
  greet: function() {
    console.log('Привет, ' + this.name);
  }
};

user.greet(); // Привет, Анна — работает

setTimeout(user.greet, 1000); // Привет, undefined — контекст потерян!

Почему так? Потому что setTimeout вызывает функцию как обычную, а не как метод объекта. this в этом случае указывает на глобальный объект (в браузере — window), у которого нет name.

Как исправить?

Три способа:

  • Стрелочная функция — она не создаёт свой this, а берёт его из внешнего контекста.
  • Метод .bind() — привязывает контекст навсегда.
  • Хранение ссылки на this (старый способ, лучше не использовать).
// Исправление: стрелочная функция
const user = {
  name: 'Анна',
  greet: function() {
    console.log('Привет, ' + this.name);
  }
};

setTimeout(() => user.greet(), 1000); // Привет, Анна

// Или с bind
setTimeout(user.greet.bind(user), 1000); // Привет, Анна

Ошибка №3: Асинхронность — «Почему мой fetch возвращает Promise?»

JavaScript — однопоточный язык, но он умеет работать асинхронно через колбэки, промисы и async/await. Новички часто совершают одну и ту же ошибку: пытаются использовать результат асинхронной операции как синхронный.

Пример: запрос к API

// Ошибка: пытаемся получить данные до их загрузки
let data = fetch('https://api.example.com/users');
console.log(data); // Promise {<pending>} — не то, что вы ждали

fetch возвращает Promise, а не сами данные. Вы не можете просто присвоить результат переменной и использовать его сразу.

Как правильно?

Используйте async/await — это самый читаемый способ работы с асинхронностью.

// Правильно: async/await
async function getUsers() {
  try {
    const response = await fetch('https://api.example.com/users');
    const data = await response.json();
    console.log(data); // Теперь это реальные данные
  } catch (error) {
    console.error('Ошибка загрузки:', error);
  }
}

getUsers();

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

Ошибка №4: Сравнение с «==» вместо «===»

Казалось бы, мелочь. Но эта мелочь — одна из самых частых ошибок в JavaScript, которая приводит к трудноуловимым багам. Оператор == (нестрогое равенство) выполняет приведение типов, что может дать неожиданные результаты.

Посмотрите на этот ужас:

console.log(5 == '5');    // true — строка стала числом
console.log(0 == false);  // true — false превратился в 0
console.log(null == undefined); // true — они считаются равными
console.log([] == false); // true — пустой массив стал false

Если вы используете == в условиях, то легко получить логическую ошибку, которая сломает всю бизнес-логику. Например, проверка на пустую строку может внезапно пропустить 0.

Золотое правило:

Всегда используйте === (строгое равенство). Оно сравнивает и значение, и тип, не делая никаких магических преобразований.

console.log(5                

Блоги

Рекомендаций по книгам