Весёлая консолька

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

Должна сказать, что я довольно редко пишу 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 );

Разный вывод DOM-элементов

В первом случае выведется код элемента, во втором — 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] );

Rainbow

Чтобы покрасить только часть строки, один из стилей можно задать пустым:

console.log ( '%c text1 %c text2', 'color: crimson;', '' );

Двухцветный текст

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

Таблицы

Может, таблица выглядит не очень читабельно, но всё же это лучше списка свёрнутых объектов, к тому же она позволяет окинуть взглядом сразу весь массив.

Также можно выделять из общего потока отдельные строчки, используя console.info() и console.warn():

console.info ( 'your text' );
console.warn ( 'your text' );

warn & info

Они работают как обычный console.log(), только добавляют иконки в начало строки (а console.warn() ещё и фон).

Ещё можно выводить сообщения об ошибке и дополнительную отладочную информацию. Например, с помощью console.error():

console.error ( 'Houston, we have a problem' );

console.error()

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.assert()

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

console.trace ( 'Hello' );

console.trace()

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

console.group ( 'Animals' );
console.log ( 'cat' );
console.log ( 'dog' );
console.groupEnd ();

console.group()

Чтобы группа была по умолчанию свёрнута, вместо console.group() используется console.groupCollapsed().

А ещё можно подсчитывать вызовы функций с помощью console.count():

function myFunc() {
    console.count ( 'myFunc() called' );
}

for (var i = 0; i < 3; i++) {
    myFunc ();
}

console.count()

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

Ссылки по теме:
Console API Reference
developer.mozilla.org/en-US/docs/Web/API/Console
Если вы нашли ошибку или неточность, вы можете отредактировать статью с помощью prose.io, а также можно написать мне в комментариях или в Twitter.
Система комментирования от Disqus