Устранение основных ошибок в JavaScript

JavaScript — это язык программирования, который используется во фронтенд- и бэкенд-разработке. Однако иногда правильно расшифровать сообщение об ошибке в JavaScript бывает немного сложно. При устранении проблем в приложени очень важно понимание того, на что ссылается сообщение об ошибке. Современные браузеры поставляются со встроенными утилитами отладки, которые помогают в этом. Каждый браузер по-разному визуально выводит сообщения об ошибках. Но эти сообщения подскажут вам, что происходит с кодом JavaScript.

В этом мануале мы рассмотрим три распространенных типах ошибок JavaScript, которые возникают в среде браузера: ReferenceError, SyntaxError и TypeError. Чтобы следовать этому туториалу, вы должны иметь представление о JavaScript и консоли разработчика.

Читайте также: Использование консоли разработчика JavaScript

Примеры в этом туториале помогут вам ознакомиться с распространенными сообщениями об ошибках. Сообщения в примерах из браузера Chrome, в Firefox или Edge могут содержать немного другую информацию, но типы ошибок одинаковы для всех.

Типы ошибок JavaScript

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

VM170:1 Uncaught ReferenceError: shark is not defined
    at <anonymous>:1:1

Если разобрать это сообщение, вы узнаете, что ReferenceError — это тип обнаруженной ошибки. После двоеточия следует сообщение, которое описывает ошибку: shark is not defined. Последняя строка в этом сообщении указывает, где именно произошла ошибка в коде: 1:1.

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

Ошибка ReferenceError

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

Неопределенные переменные

Например, если вы неправильно написали название переменной при выполнении console.log(), вы получите ошибку ReferenceError:

let sammy = 'A Shark dreaming of the cloud.';

console.log(sammmy);

Вывод будет следующим:

Uncaught ReferenceError: sammmy is not defined
    at <anonymous>:1:13

Переменная sammmy с тремя буквами m не существует и не определена. Чтобы исправить эту ошибку, можно обновить переменную и написать ее правильно,а затем повторно выполнить команду. Если все прошло успешно, то вы не получите сообщение об ошибке. В целом рекомендуется всегда заранее проверять код на наличие опечаток, чтобы избежать ошибок с неопределенными переменными.

Доступ к переменной до ее объявления

Также вы можете столкнуться с ошибкой при попытке получения доступа к переменной до ее объявления в коде:

function sharkName() {
    console.log(shark);

    let shark = 'sammy';
}

VM223:2 Uncaught ReferenceError: Cannot access 'shark' before initialization
    at sharkName (<anonymous>:2:17)
    at <anonymous>:1:1

В этом примере при выполнении console.log(shark) переменная shark объявлена после вызова, что приводит к ошибке. Как вы сами знаете, сначала нужно объявить переменную, а уже потом пытаться получить к ней доступ.

Примечание: из-за того, как работают объявления let и const, объявления переменных всплывают, но в предыдущем примере они не доступны, потому что находятся в так называемой “временной мертвой зоне” (Temporal Dead Zone). Чтобы избежать этого, рекомендуется объявлять переменные let и const в начале области.

Чтобы исправить эту ошибку, объявите переменную shark перед выполнением команды console.log():

function sharkName() {
    let shark = 'sammy';

    console.log(shark);
}

Ошибка ReferenceError часто связана с переменными и областью видимости. Это выходит за рамки данного мануала.

Читайте также: Переменные, области и поднятие переменных в JavaScript

Ошибка SyntaxError

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

Отсутствует закрывающий знак

Например, когда вы пишете функцию и забываете закрыть круглую скобку, ), чтобы заключить свой код, вы получите SyntaxError с очень конкретным сообщением об отсутствующем элементе:

function sammy(animal) {
    if(animal == 'shark'){
        return `I'm cool`;
    } else {
        return `You're cool`;
    }
}

sammy('shark';

Вы получите:

Uncaught SyntaxError: missing ) after argument list

В сообщении об ошибке указывается отсутствующий символ в коде. В этом примере в вызове функции sammy отсутствует закрывающая скобка ):

. . .

sammy('shark');

Отсутствие завершающей фигурной скобки } в конце функции или квадратной ] в массиве также может привести к этой ошибке. Убедитесь, что вы правильно закрываете функции, массивы и объекты.

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

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

function sammy(animal) {
    let animal = 'shark';
}

Получаем:

VM132:2 Uncaught SyntaxError: Identifier 'animal' has already been declared

Чтобы исправить эту ошибку, убедитесь, что вы используете уникальные и конкретные имена переменных внутри тела функции. Объявив новое имя переменной, например, animalType, вы устраните конфликт между параметром функции и переменной let в теле:

function sammy(animal) {
    let animalType = 'shark';
}

Если в теле функции вы собираетесь изменять параметр, не объявляйте переменную с таким же именем. Например, вы можете удалить объявление let внутри тела функции:

function sammy(animal) {
    animal = 'shark';
}

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

Случайные символы

Иногда в коде встречаются опечатки: к примеру, пропущенные символы (как мы уже видели выше) или ненужные повторения символов. Посмотрите на следующий код:

let sharkCount = 0;

function sammy() {
    sharkCount+;
    console.log(sharkCount);
}

Вы получите:

Uncaught SyntaxError: Unexpected token ';'

Дополнительным элементом в этом примере является знак плюс (+) после sharkCount внутри тела функции:

. . .
function sammy() {
    sharkCount++;
    console.log(sharkCount);
}

При возникновении ошибки SyntaxError: Unexpected token проверьте код на наличие пропущенных или дополнительных операторов, таких как знак плюс (+) в примере.

Ошибка TypeError

TypeError возникает, когда значение функции или переменной имеет непредвиденный тип. 

Читайте также: Типы данных в JavaScript

Методы массивов и объекты

Одна из распространенных ошибок — использование метода массива для итерации объекта. Например, перебрать объект с помощью метода .map() нельзя, потому что он доступен только для массивов:

const sharks = {
    shark1: 'sammy',
    shark2: 'shelly',
    shark3: 'sheldon'
}

sharks.map((shark) => `Hello there ${shark}!`);

Вы получите:

Uncaught TypeError: sharks.map is not a function
    at <anonymous>:1:8

Один из вариантов исправления предыдущего примера — использовать цикл for…in, который работает с объектами:

const sharks = {
    shark1: 'sammy',
    shark2: 'shelly',
    shark3: 'sheldon'
}

for (let key in sharks) {
    console.log(`Hello there ${sharks[key]}!`);
}

Также можно преобразовать объект sharks в массив, чтобы использовать метод .map():

const sharks = ['sammy', 'shelly', 'sheldon'];

sharks.map((shark) => `Hello there ${shark}!`);

Когда вы работаете с разными массивами и объектами, методы легко перепутать. Убедитесь, что метод соответствует типу данных, с которыми вы работаете.

Правильные методы деструктуризации

Аналогично, попытка выполнить итерацию над объектом с деструктуризацией массива приведет к ошибке TypeError:

const shark = {
    name: 'sammy',
    age: 12,
    cloudPlatform: 'sammy'
}

const [name, age, cloudPlatform] = sharks;

Получаем:

VM23:7 Uncaught TypeError: sharks is not iterable
    at <anonymous>:7:26

Один из способов решить эту проблему — использовать деструктуризацию объекта, чтобы создавать новые переменные на основе ключей объекта:

const shark = {
    name: 'sammy',
    age: 12,
    cloudPlatform: 'sammy'
}

const {name, age, cloudPlatform} = shark;

console.log(name);

Получим следующий вывод:

sammy

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

Подводим итоги

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

Читайте также: 

Tags:

Добавить комментарий