Весёлая консолька
Недавно мне пришлось отлаживать очень капризный скрипт, в котором, по ощущениям, происходили какие-то паранормальные явления. Чтобы найти проблему, понадобилось вывести в консоль браузера большое количество отладочной информации. С одной стороны, так стало удобнее искать ошибку, с другой — содержимое консоли превратилось в бесконечную колбасу однообразного текста, и с этим надо было что-то делать.
Должна сказать, что я довольно редко пишу Javascript, поэтому заинтересовавшись возможностями консоли узнала много нового.
Чтобы просто вывести что-то в консоль, используется console.log()
:
console.log ( 'Что-нибудь' );

Таким образом можно выводить любые типы данных — строки, числа, массивы, объекты:
var str = 'Главный вопрос жизни вселенной и всего такого';
var num = 42;
var fruitsList = [ 'apple', 'pear', 'banana' ];
var fruitsObj = {
'apple': {
color: 'red',
seeds: true
},
'pear': {
color: 'green',
seeds: true
},
'banana': {
color: 'yellow',
seeds: false
}
};
console.log ( str );
console.log ( num );
console.log ( fruitsList );
console.log ( fruitsObj );

Код подсвечен, вложенные элементы объектов свёрнуты.
Как этот вывод можно улучшить? Мы видим в консоли содержимое переменных, но не видим их названий. Самый очевидный способ — добавить название перед выводимыми данными:
console.log ( 'Строка: ' + str );
console.log ( 'Число: ' + num );
console.log ( 'Массив: ' + fruitsList );
console.log ( 'Объект: ' + fruitsObj );

При этом все значения переменных приведутся к строке. Для строк и чисел это не проблема, массив потеряет подсветку, хотя и останется читабельным, а вот объект превратится в строку [object Object], и содержимое объекта теперь нельзя ни прочитать, ни развернуть.
Так себе вариант, есть способ получше: можно передавать в console.log()
список переменных, разделённых запятой, и в этом случае они будут выведены корректно:
console.log ( 'Строка:', str );
console.log ( 'Число:', num );
console.log ( 'Массив:', fruitsList );
console.log ( 'Объект:', fruitsObj );

И так тоже можно:
console.log ( 'Всё сразу:', str, num, fruitsList, fruitsObj );

Передаваемые переменные можно выводить не только одну за другой, но и в более управляемом виде:
console.log ( 'Сначала строчка: "%s", потом число: %i', str, num );

Переменные точно также передаются в функцию списком, а для их вставки в конкретное место строки используются указатели, которые заодно отвечают и за формат вывода:
%s
— в виде строки;
%d
или %i
— в виде числа;
%f
— в виде числа с плавающей точкой;
%o
— в виде разворачиваемого DOM-элемента;
%O
— в виде разворачиваемого JavaScript-объекта;
%c
— оформляет вывод с соответствии с CSS, переданным дополнительным параметром.
Переменные перед выводом в консоль приводятся к заданному формату. При этом важно правильно выбрать подходящий указатель, потому что иначе результат может получиться некорректным или просто нечитабельным:
var str = 'Главный вопрос жизни вселенной и всего такого';
var float = 12.34;
var fruitsList = [ 'apple', 'pear', 'banana' ];
console.log ( 'str: %i: ', str );
console.log ( 'float: %i', float );
console.log ( 'fruitsList: %O:', fruitsList );

Строка не смогла привестись к числу, и получилось NaN
, число с плавающей точкой потеряло свою десятичную часть, а массив вывелся в виде разворачиваемого объекта, и теперь придется кликнуть, чтобы увидеть его содержимое.
Форматы %o
и %O
особенно полезны для вывода элементов страницы:
var h1Elem = document.querySelector('h1');
console.log ( '%o', h1Elem );
console.log ( '%O', h1Elem );

В первом случае выведется код элемента, во втором — Javascript-объект. При этом если нет необходимости выводить вспомогательный текст, аналогичный результат можно получить воспользовавшись просто console.log()
и console.dir()
:
console.log ( h1Elem ); // код элемента
console.dir ( h1Elem ); // Javascript-объект
Результат работы этого кода будет таким же, как на скрине выше.
Из всех указателей мне больше всего полюбился последний: %c
— стилизующий текст, потому что именно он помог мне привести однообразную колбасу в консоли в более-менее читабельный вид.
Для того, чтобы задать оформление тексту, CSS-код нужно передать отдельным параметром, причем первым параметром в этом случае должна быть строка с указателями, вторым — строка с CSS, третьим — данные, которые нужно вывести.
Пример:
var str = 'Главный вопрос жизни вселенной и всего такого';
console.log ( '%c%s', 'color: green; font: 1.2rem/1 Tahoma;', str );

Ещё удобнее будет вынести стили в отдельную переменную, тогда их можно будет использовать повторно:
var str = 'Главный вопрос жизни вселенной и всего такого';
var style = ['padding: 1rem;',
'background: linear-gradient( gold, orangered);',
'text-shadow: 0 2px orangered;',
'font: 1.3rem/3 Georgia;',
'color: white;'].join('');
console.log ( '%c%s', style, str );

Так можно управлять отступами, фоном и оформлением текста. Какие-то штуки работать не будут, например, box-shadow
, но и того, что есть, вполне достаточно, чтобы добавить в консоль немного красоты:

Для своих целей я заготовила несколько стилей:
var consoleStyles = {
'h1': 'font: 2.5em/1 Arial; color: crimson;',
'h2': 'font: 2em/1 Arial; color: orangered;',
'h3': 'font: 1.5em/1 Arial; color: olivedrab;',
'bold': 'font: bold 1.3em/1 Arial; color: midnightblue;',
'warn': 'padding: 0 .5rem; background: crimson; font: 1.6em/1 Arial; color: white;'
};
и функцию, которая избавила меня от необходимости формировать руками набор параметров и форматирование строки:
function log ( msg, style ) {
if ( !style || !consoleStyles[ style ] ) {
style = 'bold';
}
console.log ( '%c' + msg, consoleStyles[ style ] );
}
Пример использования:
log ( 'Заголовок 1', 'h1' );
log ( 'Заголовок 2', 'h2' );
log ( 'Заголовок 3', 'h3' );
log ( 'Жирный текст', 'bold' );
log ( 'Ошибка', 'warn' );

Таким образом из вот такой колбасы скучного текста

можно получить вот такое:

По-моему, так гораздо лучше, особенно если отладочной информации много и в ней легко потеряться.
Чтобы использовать в одной строке несколько стилей, надо каждый из них указать отдельным параметром, а затем с помощью %c
задавать в тексте начало нового стиля:
var styles = [
'background: red',
'background: orange',
'background: gold',
'background: yellowgreen',
'background: skyblue',
'background: steelblue',
'background: darkviolet'
];
console.log ( '%c R %c A %c I %c N %c B %c O %c W ',
styles[0], styles[1], styles[2], styles[3],
styles[4], styles[5], styles[6] );

Чтобы покрасить только часть строки, один из стилей можно задать пустым:
console.log ( '%c text1 %c text2', 'color: crimson;', '' );

Если не хочется заморачиваться с раскрашиванием, для вывода большого количества данных можно воспользоваться console.table()
:

Может, таблица выглядит не очень читабельно, но всё же это лучше списка свёрнутых объектов, к тому же она позволяет окинуть взглядом сразу весь массив.
Также можно выделять из общего потока отдельные строчки, используя console.info()
и console.warn()
:
console.info ( 'your text' );
console.warn ( 'your text' );

Они работают как обычный console.log()
, только добавляют иконки в начало строки (а console.warn()
ещё и фон).
Ещё можно выводить сообщения об ошибке и дополнительную отладочную информацию. Например, с помощью console.error()
:
console.error ( 'Houston, we have a problem' );

console.error()
ничего не проверяет, она просто выводит сообщение, оформленное определённым образом. Чтобы сообщение выводилось только при соблюдении заданных условий, можно использовать console.assert()
:
var fruitsObj = {
'apple': {
color: 'red',
seeds: true
}
};
var expression = fruitsObj.apple.color === 'blue';
console.assert ( expression, 'There is no blue apple' );
Сообщение будет выведено только если expression
будет равно false
:

Чтобы просто вывести в консоль сообщение с отладочной информацией, можно использовать console.trace()
:
console.trace ( 'Hello' );

Для визуальной группировки сообщений можно использовать console.group()
и console.groupEnd()
, обозначающие начало и конец группы соответственно:
console.group ( 'Animals' );
console.log ( 'cat' );
console.log ( 'dog' );
console.groupEnd ();

Чтобы группа была по умолчанию свёрнута, вместо console.group()
используется console.groupCollapsed()
.
А ещё можно подсчитывать вызовы функций с помощью console.count()
:
function myFunc() {
console.count ( 'myFunc() called' );
}
for (var i = 0; i < 3; i++) {
myFunc ();
}

В консоли можно делать и другие интересные вещи, вроде измерения времени выполнения кода. Также умные ребята для отладки используют debugger
и точки остановки (breakpoints), но это уже совсем другая история.
- Метки:
- JS,
- инструменты