Среда настроена и редактор открыт. Теперь перед нами вопрос, за которым скрывается кое-что важное: что именно Node.js делает, когда мы запускаем файл? И что происходит, если что-то идёт не так?
Этот урок — не про сложный синтаксис, а про устройство программы как таковой: из чего она состоит, как выполняется и что Node.js сообщает нам об ошибках.
Программа — это список инструкций
Программа на JavaScript — это файл с текстом. Node.js открывает этот файл, читает его сверху вниз и выполняет каждую строку по очереди. Порядок имеет значение: то, что написано первым, выполняется первым, и никак иначе.
Каждая отдельная команда называется инструкцией (от лат. instructio — наставление, указание). По-английски — statement, буквально «высказывание»: одна законченная мысль, которую программа должна выполнить. В JavaScript инструкции принято разделять точкой с запятой, хотя в большинстве случаев язык способен угадать конец инструкции самостоятельно — этот механизм называется ASI (Automatic Semicolon Insertion, автоматическая вставка точки с запятой). Для новичка совет один: точку с запятой лучше ставить явно. Это не ошибка, а хороший тон: код становится предсказуемым, и неожиданностей при чтении возникает меньше.
Посмотрим на простой пример с несколькими вызовами console.log() подряд:
console.log("Первая строка");
console.log("Вторая строка");
console.log("Третья строка");
Вывод в терминале:
Первая строка
Вторая строка
Третья строка
Порядок строк в выводе в точности совпадает с порядком инструкций в файле. Если поменять местами вызовы в коде, изменится и вывод — Node.js не угадывает намерения автора, а следует тексту буквально.
Теперь немного подробнее о самом console.log(). До сих пор мы передавали ему одно значение, но скобки принимают любое количество значений через запятую — каждое из них называется аргументом (от лат. argumentum — довод, доказательство; в программировании — значение, которое передаётся в функцию при вызове). console.log() выводит все переданные аргументы через пробел:
console.log("Результат:", 42);
console.log("Год:", 1995, "Месяц:", 5);
Результат: 42
Год: 1995 Месяц: 5
Что такое «функция» и почему console.log() принимает аргументы — мы разберём подробно в одном из следующих уроков. Пока достаточно рабочего образа: console.log() — это команда с именем, которой можно передать данные. Несколько значений через запятую — несколько аргументов, все они окажутся в одной строке вывода, разделённые пробелами.
Комментарии
Код читает не только компьютер. Его читает и автор через месяц, когда подробности выветрились из памяти, и коллега, которому нужно разобраться в чужой программе. Для таких случаев существуют комментарии — строки, которые Node.js при выполнении полностью игнорирует. Они предназначены исключительно для человека.
Комментарии бывают двух видов. Первый — однострочный: всё, что написано после двух косых черт // до конца строки, Node.js не выполняет.
// Это однострочный комментарий — вся строка игнорируется
console.log("Hello"); // А здесь комментарий в конце строки с кодом
Второй вид — блочный комментарий: открывается символами /* и закрывается */. Между ними может быть сколько угодно строк.
/*
Это блочный комментарий.
Можно писать на нескольких строках.
Node.js проигнорирует всё от /* до закрывающего * с /.
*/
console.log("Эта строка выполняется");
Оба синтаксиса пришли из языка C, созданного в 1972 году, и с тех пор стали стандартом для большинства языков программирования: Java, C++, C#, Go, Rust — во всех них комментарии выглядят точно так же. // происходит от двух символов slash (косая черта). Блочный /* */ — немного старше, он появился в ранних версиях C ещё до того, как однострочные комментарии стали повсеместными.
Комментарии пишут по нескольким поводам: чтобы объяснить неочевидное решение, оставить напоминание, или временно отключить строку кода без её удаления. Последнее — один из самых частых приёмов при отладке:
console.log("Работает");
// console.log("Временно отключено");
console.log("Тоже работает");
Вывод:
Работает
Тоже работает
Закомментированная строка существует в файле, но на выполнение не влияет. Это удобно: не нужно помнить, что именно было в строке — достаточно убрать //, и она снова заработает.
Ошибки: синтаксическая ошибка и ошибка ссылки
Ошибки — обычная часть работы с кодом, а не признак неудачи. Node.js сообщает о них в терминале, и эти сообщения устроены так, чтобы помочь найти проблему — если знать, как их читать.
На этом этапе чаще всего встречаются два вида ошибок.
Первый — SyntaxError (от греч. syntaxis — составление, строение). Это ошибка в структуре кода: Node.js не может разобрать файл и поэтому не выполняет из него вообще ничего — ни строки до ошибки, ни строки после. Если, например, не закрыть кавычки:
console.log("Привет"
Node.js выведет примерно следующее:
/path/to/file.js:1
console.log("Привет"
^^^^^^^
SyntaxError: Unterminated string constant
Первая строка сообщения — путь к файлу и номер строки, где обнаружена проблема. Затем идут тип ошибки (SyntaxError) и её описание: Unterminated string constant — незакрытая строковая константа. Стрелочки под кодом указывают на проблемное место.
Второй вид ошибок — ReferenceError (от лат. referentia — ссылка, отсылка). Она возникает, когда в коде встречается имя, которого Node.js не знает — например, из-за опечатки:
consol.log("Привет");
ReferenceError: consol is not defined
Здесь consol написано без буквы e, и Node.js не находит такого имени. В отличие от SyntaxError, при ReferenceError программа успевает выполнить всё написанное до проблемной строки, а затем останавливается.
Привычка читать сообщения об ошибках — один из главных навыков программиста, и формируется он с первых же дней. Схема проста: смотреть на первую строку (файл и номер строки), затем на тип ошибки (SyntaxError, ReferenceError), затем на описание после двоеточия. Длинный «трейсбек» — список строк файлов под сообщением об ошибке — обычно нужен при более сложных программах; сейчас достаточно первых двух строк.
Сообщение об ошибке — это подсказка, а не приговор. Оно говорит ровно то, что пошло не так, и в большинстве случаев сразу указывает, где искать причину.
В этом уроке мы разобрали устройство программы на самом базовом уровне. Node.js читает файл построчно, сверху вниз, и выполняет каждую инструкцию по очереди — порядок в коде определяет порядок выполнения.
console.log() принимает несколько аргументов через запятую и выводит их через пробел в одну строку терминала.
Комментарии — строки для человека, которые Node.js игнорирует. Однострочный комментарий начинается с // и продолжается до конца строки; блочный комментарий заключается между /* и */ и может занимать любое количество строк.
Два типа ошибок, с которыми вы уже можете столкнуться:
- SyntaxError — Node.js не может разобрать структуру кода; файл не выполняется вовсе.
- ReferenceError — в коде встречается имя, которое Node.js не знает; программа выполняется до этой строки, затем останавливается.
Читать сообщение об ошибке начинайте с первой строки: там указаны файл, номер строки и тип ошибки — этого обычно достаточно, чтобы найти проблему.