Вам, вероятно, уже известен метод console.log и несколько других, но на деле их существует более 20 видов. Каждый из них по-своему полезен, и используя их по назначению, вы заметно повысите качество отладки.
Основные методы консоли
Начнем с 5 основных методов:
log
debug
info
warn
error
Все вышеперечисленные методы работают одинаково, выводя указанную информацию в консоль. Разница между ними лишь в том, как она в ней отображаются. Для сравнения, давайте посмотрим отдельно на каждый метод.
Если вы захотите повторить то же самое, возможно, у вас не отобразятся некоторые из методов. Это оттого, что в консоли есть возможность скрыть или показать уровни
Возможность выбирать уровни является одной из причин, почему эти методы могут быть так полезны. Если вам потребуется отобразить в консоли только ошибки, выбрав соответствующий уровень, вы существенно ускорите отладку.
Примеры использования
Простейший способ использования этих методов - передать в них строку или другое значение. Они выведут это значение в консоль. Вы можете пойти дальше и передать несколько значений в качестве аргументов
console.log("Hello", "World", { name: "Leslie" })
// Hello World {name: 'Leslie'}
Это применимо для всех 5 основных методов, и является удобным способом вывода информации в одну строку вместо того, чтобы отображать каждое значение отдельно, используя один и тот же метод несколько раз.
Отображение в реальном времени
Браузер, помогая нам в отладке, всегда отображает актуальные значения в объекте
const person = { name: "Leslie" }
console.log(person)
person.name = "Sally"
В консоли браузера, актуальное значение ключа name
объекта person
будет вычислено в тот момент, когда мы раскроем сам объект
Иногда это действительно бывает полезно, но чаще всего мы хотим знать, каким было значение в момент вывода его в консоль. Простой способ добиться нужного результата это клонирование объекта
const person = { name: "Leslie" }
console.log({ ...person })
person.name = "Sally"
Здесь есть неприятность: код, описанный выше, не работает с объектами, которые имеют какую-либо вложенность. В такой ситуации вам потребуется либо написать собственный метод для глубокого клонирования, либо воспользоваться имеющимся:
const person = { name: "Leslie" }
console.log(JSON.parse(JSON.stringify(person)))
person.name = "Sally"
Улучшенный вывод данных
Теперь, когда мы закончили с основными методами, можно посмотреть на более продвинутые.
Dir
Метод dir
подозрительно схож с одним из тех, которые мы разобрали ранее -- методом log
, с одной лишь оговоркой: log
выводит HTML-элементы в формате HTML, в то время как dir
отображает список их свойств
Table
Метод table
используется для отображения объектов в массиве в виде таблицы, визуально упрощая их восприятие
Группирование
Вывод данных в консоль также изменяют следующие 3 взаимосвязанных между собой метода:
group
groupCollapsed
groupEnd
Названия этих методов говорят сами за себя. Оба group
и groupCollapsed
создают группу, но groupCollapsed
создает ее уже закрытой. Сообщения, выводимые в консоль будут частью группы до тех пор, пока она не будет закончена методом groupEnd
.
console.log("Вне группы")
console.group()
console.log("Внутри первой группы")
console.log("Все еще первая группа")
console.groupEnd()
console.group("Название второй группы")
console.log("Внутри второй группы")
console.groupCollapsed()
console.log("Внутри вложенной группы")
console.groupEnd()
console.log("Все еще вторая группа")
console.groupEnd()
В этом примере мы создали 3 разных группы. В первую группу не передавался аргумент, поэтому она имеет стандартный заголовок «console.group». Во вторую мы передали в качестве аргумента строку «Название второй группы», вложив в нее еще одну группу, используя метод groupCollapsed
. Как вы уже могли догадаться, в группе в виде вложенности может находиться еще несколько. Заметьте, группа созданная с использованием groupCollapsed
не раскрыта.
Методы группирования будут полезны, если вам нужно вывести в консоль большое количество относящейся друг к другу информации, и вы не хотите заполнять ею всю консоль.
Отладка производительности
Таймер
Следующие несколько методов просто понять, поскольку их задача заключается в том, чтобы вычислить время между запуском и окончанием какой-либо операции. В нашем случае это вызов функции
console.time()
slowFunction()
console.timeEnd()
// default: 887.69189453125 ms
console.time("Label")
slowFunction()
console.timeEnd("Label")
// Label: 863.14306640625 ms
Так же, как и в группу, в таймер можно передать аргументом заголовок. Для того, чтобы связать запуск и окончание одного и того же таймера, тот же заголовок нужно передать и в завершающий метод timeEnd
.
Вдобавок к этим двум методам имеется еще один -- timeLog
. Используя timeLog
, можно вывести текущее время с начала таймера, не останавливая его.
console.time("Label")
slowFunctionOne()
console.timeLog("Label")
slowFunctionTwo()
console.timeEnd("Label")
// Label: 920.578125 ms
// Label: 1855.43896484375 ms
Не забудьте передать в него соответствующий заголовок, как в примере выше.
Профайлер
Теперь рассмотрим то, как поднять отладку производительности на следующий уровень, используя профайлер.
console.profile()
slowFunction()
console.profileEnd()
console.profile("Label")
slowFunction()
console.profileEnd("Label")
Что он делает: метод profile
запускает одноименный профайлер, встроенный в инструменты разработчика, записывая различную информацию, связанную с производительностью.
Примечание: в зависимости от браузера, профайлер может различаться внешне и находиться в разных местах. Также, профайлер на текущий момент не является стандартизированным. Это означает, что некоторые браузеры его не поддерживают, а в тех, где он есть, способен работать некорректно. По этой причине я не рекомендую его использование.
Разное
Последние несколько методов, о которых хотелось бы поговорить, вряд ли можно причислить к предыдущим категориям, но тем не менее они невероятно полезны.
assert
Мой фаворит в этой категории -- метод assert.
Assert, в отличие от основных методов, первым параметром принимает boolean
значение. Если это значение находится в состоянии true
, вывод информации в консоль будет отменен, и наоборот
const n = 2
console.assert(n === 1, "Переменная n не равна одному")
Ту же логику работы демонстрирует код ниже
const n = 2
if (n !== 1) console.error("Переменная n не равна одному")
clear
Проще метода не найти. Все что он делает - очищает консоль
console.clear()
count и countReset
count
отображает количество вызовов данной функции. Нетрудно догадаться, что countReset
очищает текущий счет, начиная его заново
console.count()
console.count()
console.countReset()
console.count()
// default: 1
// default: 2
// default: 1
console.count("Label")
console.count("Label")
console.countReset("Label")
console.count("Label")
// Label: 1
// Label: 2
// Label: 1
trace
Последний метод, который мы рассмотрим, называется trace.
Простой метод, отображающий информацию о том, какая из функций вызвала другую функцию. Может быть также полезен, когда нужно проследить за вызовами функций внутри других функций
function firstFn() {
function secondFn() {
console.trace();
}
secondFn();
}
firstFn();
Заключение
Могли ли вы представить, что существует столько методов веб-консоли? Меня и самого удивило их количество и разнообразие.
Надеюсь, хотя бы один из этих методов поможет вам улучшить качество отладки.
Комментарии (10)
makar_crypt
21.05.2022 14:54несколько лет назад видел что в chrome dev tool есть свой селектор css как jquery не напомните ? там как то $_.()
Alternator
23.05.2022 02:30$0 - текущий выбранный в инспекторе элемент
$1 - $4 - предыдущие выбранные элементы
qbz
22.05.2022 00:06Щас как расскажу вам тайну!
Короче в Node.js есть еще приватный консоль-лог. Этоprocess._rawDebug
. Разница сconsole.log
в том, что приватная версия не триггерит никаких асинхронных апишек. Вот например можно разницу увидеть в использованииasync_hooks
:import { createHook } from 'async_hooks' createHook({ init: () => { console.log('oops') // <- вот тут будет max call stack size exceeded process._rawDebug('oops') // <- тут нет } }).enable()
defolt0
23.05.2022 11:51Прикольно узнать такие фишки в консоли. Только одного не понял: в чём разница console.log и console.info если с визуальной точки зрения, они одинаковые?
demimurych
23.05.2022 16:17Работа над любым материалом подобного характера, должна начинаться с чтения первоисточника.
Для любого программиста, первоисточником является официальная спецификация.
Не mdn, не материал другого человека, а официальная спецификация.Посмотрим на примере этого материала, чтобы с ним стало если бы его автор, так и поступил. То есть начал бы с чтения спецификации.
Мы бы узнали, что
Мы собираемся говорить не о командах консоли. А о имплементации определенного API, к которому, зачастую, можно иметь доступ в консоли некоторых host сред. Но это не сама консоль.
console (именно так с маленьнкой буквы) это API, которое прямого отношения к JavaScript не имеет. И целиком зависит от host implemetation. То есть большая часть ее машинерии лежит на совести host системы. host система - это, в рамках спецификации JavaScript, среда для работы самого JavaScript. Например Браузер, Node это все host enviroment для JavaScript.
Мы бы поняли, что поведение этого API может не только отличаться в случае разных host сред, но и полностью отсутствовать. Об этом нужно помнить.
Например, метод console.log совсем не обязательно будет что-то показывать в реальной консоли host среды. host среда может так реализовать Printer что вывод методов нашего API будет лежать где-то в другом месте. Хоть в файле.
Представляет из себя API - namespace console насчитывающий ровно 19 методов:
Loggind: assert, clear, debug, error, info, log, table, trace, warn, dir, dirxml,
Counting: count, countReset,
Grouping: group, groupCollapsed, groupEnd,
Timing: time, timeLog, timeEnd.
API ориентировано, на работу с артефактами JavaScript спецификации, как следствие, поведение методов API максимально приближено к поведению JavaScript. Как следствие, утверждение автора о Отображение в реальном времени является выдумкой, свидетельствующей о плохом знании базы стандарта Ecma.
## Как работают методы API console
На самом деле, вывод любого метода рассматриваемого API, делает только то, что от него просят, а именно если вы отправили в метод идентификатор, то показана вам будет информация по идентификатору. Многие ошибаются, думая, что если они отправили в API идентификатор указывающий на обьект, то API им отправит в stdOut этот обьект. Это не так. В stdOut будет отправлено то, что вы и попросили - то есть то, что находится по ссылке из идентификатора. Подобное заблуждение распространено среди подавляющего большинства JS разработчиков, не знающих что в JS есть только один - ссылочный тип, идентификатор. Никаких переменных или чего либо другого характерного для других языков в JS нет.
Возможность "развернуть" "свернуть" обьекты это host implementation, то есть то, что решили сделать программисты конкретной host среды, в рамках реализации двух видов форматов спецификации для обьектов: optimally useful formatting и generic JavaScript object formatting. Которые, как мы уже понимаем, могут быть реализованы как вздумается программисту конкретной host.
## Метод Dir как пример
Показательным тому примером может служить глава про Метод Dir. Где автор материала демонстрирует как раз пример заблуждения возникшего в силу непонимания как и что работает. Метод Dir форматирует вывод в соотвествии с host implementation для формата generic JavaScript object formatting. То есть в формате который должен наглядно показать структуру обьекта. Метод log же использует optimally useful formatting, задача которого отформатировать вывод в оптимальный вид. Точнее говоря в тот вид, который программист Host считвет оптимальным. Иными словами, никакого форматирования в html, как сказано в статье там нет. А есть решение конкретной группы программистов в данном случае отформатировать вывод подобным образом.
Такие методы как profile, dir, debug, monitor и так далее - это специфические реализации Google Developer Tools. И к API console они никакого отношения не имеют. То есть они присутствуют только в нем и нигде больше.
## Игого
Я думаю, на примере сказанного мной выше, легко убедиться в обязательном чтении спецификации. Особенно для случаев подготовки материалов для общего пользования.
Полезные ссылки:
LeshaRB
Консоль, консоли рознь, заголовок слишком абстрактный
mk2
Поддерживаю. Лучше бы в названии упоминался JS.
grieverrr
всратый кликбейт