Краткое руководство для начинающих веб-разработчиков

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

Что такое ошибки в JavaScript?

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

В приведенном ниже примере мы намерены записать приветствие в консоль, приветствуя возвращающегося пользователя.

let userName = "Max";

console.log(`Welcome back, ${userName}`;

Обратите внимание, что после списка аргументов console.log отсутствует скобка — это неправильный синтаксис. Когда мы попытаемся выполнить этот код, мы обнаружим следующее сообщение в консоли:

console.log(`Welcome back, ${name}`;
                                 ^^

SyntaxError: missing ) after argument list

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

JavaScript не является компилируемым языком, поэтому ошибки в JS являются
ошибками времени выполнения, т. е. нам сообщают о них во время работы программы или мы
наблюдаем их как результат неправильных результатов после завершения работы программы.

Однако в этой статье мы сосредоточимся на определенном типе
ошибок выполнения, которые также называются исключениями. Эти типы ошибок
возникают, когда часть кода программы не может быть выполнена, что приводит к сбою программы. Когда возникает одна такая ошибка, мы говорим, что ошибка была вызвана. При возникновении ошибки браузер или среда, в которой работает Node.js, немедленно останавливают выполнение программы.

Наиболее распространенными исключениями, с которыми сталкиваются начинающие разработчики JavaScript, являются SyntaxErrors, как мы видели в примере выше, или ReferenceErrors, которые могут возникать, когда мы пытаемся выполнить недопустимую операцию с некоторыми данными, как в примере ниже.

В этом примере мы пытаемся зарегистрировать приветствие, используя переменную с именем name, но эта переменная не существует.

let userName = "Max";

console.log(`Welcome back, ${name}`);

Таким образом, при выполнении приведенного выше кода будет вызвана следующая ошибка ReferenceError:

console.log(`Welcome back, ${name}`);
                             ^

ReferenceError: name is not defined

Где посмотреть информацию о возникших ошибках

В Гугл Хром

В браузере вы можете найти сведения о возникающих ошибках в консоли, которая находится в инструментах разработчика браузера. Если вы разрабатываете в Google Chrome, откройте Инструменты разработчика и перейдите на вкладку «Консоль». В качестве альтернативы используйте сочетание клавиш opt+ cmd + J на Mac или ctrl + shift + J на Windows/Linux.

Примечание. На обоих снимках экрана ниже код JavaScript, вызвавший ошибки, — это тот же код, что и в первом примере (SyntaxError) выше.

В терминале

Если вы работаете с Node.js, вы, скорее всего, запускаете свой код Node.js из терминала — информация о возникающих ошибках будет отображаться непосредственно в этом окне терминала.

> node example.js
/<path-to-working-directory>/example.js:3
console.log(`Welcome back, ${name}`;
                                 ^^

SyntaxError: missing ) after argument list

Что такое трассировка стека?

Трассировка стека — это вся информация, которую среда JavaScript (например, браузер или Node.js) передает нам при возникновении ошибки. Часть термина стек относится к некоторым более сложным внутренним механизмам JavaScript, но пока вы можете рассматривать его как инструмент, который среда JavaScript использует для отслеживания контекстной информации во время выполнения программы. Например, он может отслеживать локальные и глобальные переменные при выполнении кода внутри функции.

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

let greetUser = (name) => {
  console.log(`Welcome back, ${user.name}`);
}

let userName = "Max";
greetUser(userName);

Запуск приведенного выше кода вызовет ошибку. На снимке экрана ниже показана трассировка стека и ее части.

Как читать трассировку стека

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

let greetUser = (name) => {
  console.log(`Welcome back, ${user.name}`);
}

let userName = "Max";
greetUser(userName);

Предполагая, что этот код находится в файле с именем example.js, запустив его с помощью Node.js, мы получим следующую трассировку стека, зарегистрированную в консоли.

> node example.js
/<path-to-working-directory>/example.js:2
  console.log(`Welcome back, ${user.name}`);
                               ^

ReferenceError: user is not defined
    at greetUser (/<path-to-working-directory>/example.js:2:32)
    at Object.<anonymous> (/<path-to-working-directory>/example.js:6:1)
  1. Начните с чтения типа ошибки и сообщения об ошибке, так как это самая важная информация.
ReferenceError: user is not defined

Это говорит нам о том, что возникшая ошибка является ReferenceError, в частности, переменная user не определена. Эта информация поможет нам лучше понять остальную часть трассировки стека.

2. Прочитайте первые несколько строк.

/<path-to-working-directory>/example.js:2
  console.log(`Welcome back, ${user.name}`);
                               ^

Они сообщают нам, что ошибка возникла в строке 2 файла, с которым мы работаем (в данном случае это example.js). Вторая строка трассировки стека выводит рассматриваемую строку кода, выделяя первый символ, в котором произошла ошибка. Возможно, именно здесь нам придется внести изменения в код, но давайте сначала прочитаем остальную часть трассировки стека, чтобы получить полную картину.

3. Прочитайте последние строки трассировки стека.

ReferenceError: user is not defined
    at greetUser (/<path-to-working-directory>/example.js:2:32)
    at Object.<anonymous> (/<path-to-working-directory>/example.js:6:1)

Это говорит нам о том, что контекст, в котором возникла ошибка, произошел внутри функции с именем greetUser, при этом ошибка возникла в строке 2. И эта функция была вызвана в строке 6 нашего файла.

4. Теперь у нас есть вся информация, предоставленная трассировкой стека — давайте найдем ошибку, двигаясь назад по первым трем шагам.

Перечитывая наш код в строке 6, мы видим, что мы передаем строку "Max" в функцию greetUser через переменную userName. Все идет нормально.

Однако внутри функции greetUser в строке 2 сообщение об ошибке сообщало нам, что мы попытались сослаться на несуществующий объект с именем user. Такая переменная никогда не определялась. Вместо этого функция получает аргумент с именем name, который в данном случае будет строкой. Итак, мы должны ссылаться на name. Трассировка стека помогла нам найти ошибку! Теперь мы можем исправить код, как показано в обновленном примере ниже.

let greetUser = (name) => {
  console.log(`Welcome back, ${name}`);
}

let userName = "Max";
greetUser(userName);
> node example.js
Welcome back, Max

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

Ссылки и дополнительная литература