За межами console.log()

8 хв. читання

Налагодження у JavaScript — більше, ніж використання console.log для виводу значень. Багато розробників навіть не здогадуються, скільки можливостей, які значно полегшують та пришвидшують процес налагодження, приховується за межами звичайного .log.

console.log

Ви не уявляєте, скільки всього корисного у старому доброму console.log. Окрім стандартного console.log(object), можна виконати console.log(object, otherObject, string), щоб результат буде більш наочним.

Існує й інший формат: console.log(msg, values). Це щось на зразок функції sprintf у C чи PHP.

console.log('I like %s but I do not like %s.', 'Skittles', 'pus');

Отримаємо результат:

> I like Skittles but I do not like pus.

Також корисними будуть шаблони %o (тут літера «о», а не нуль) – для позначення об'єкта, %s — для рядка та %d — для decimal чи integer.

За межами console.log()

Шаблон %c використовується для CSS значень.

console.log('I am a %cbutton', 'color: white; background-color: orange; padding: 2px 5px; border-radius: 2px');
За межами console.log()

Основна незручність – немає закриваючого тегу. Тому, щоб виділити лише частину рядка робимо так:

За межами console.log()

Корисного тут не дуже багато: наша «кнопка» несправжня.

За межами console.log()

Знову ж таки, чи корисно це?

console.dir()

Функція console.dir() дуже схожа на log(), але є певні нюанси.

За межами console.log()

У результаті ми бачимо інформацію про об'єкт, як і зі звичайним console.log. Якщо ж придивитись до елементів, можна помітити цікаву особливість.

let element = document.getElementById('2x-container');

Отримаємо такий результат:

За межами console.log()

Ми відкрили декілька елементів. Тут бачимо DOM, по якому можна здійснити навігацію. З console.dir() отримуємо зовсім інший вивід:

За межами console.log()

Це більш «об'єктний» підхід до елементів. У деяких випадках вам справді може знадобитись така перевірка.

console.warn()

Найбільш очевидна альтернатива для console.logconsole.warn. Вони лише трохи відрізняються кольором позначення результату. Усе тому, що результат console.warn розглядається браузером як попередження, а не звичайна інформація. Тож результат виділяється для наочності.

Також з console.warn можна відфільтрувати усі console.log і залишити лише те, що стосується попереджень. Це особливо корисно у застосунках, що виводять багато зайвої інформації у браузер. Така фільтрація значно спростить процес налагодження.

console.table()

Функція console.table() призначена для табличних даних. З нею результат буде більш зрозумілий, ніж зі звичайним масивом об'єктів.

Для прикладу візьмемо список даних:

const transactions = [{
 id: "7cb1-e041b126-f3b8",
 seller: "WAL0412",
 buyer: "WAL3023",
 price: 203450,
 time: 1539688433
},
{
 id: "1d4c-31f8f14b-1571",
 seller: "WAL0452",
 buyer: "WAL3023",
 price: 348299,
 time: 1539688433
},
{
 id: "b12c-b3adf58f-809f",
 seller: "WAL0012",
 buyer: "WAL2025",
 price: 59240,
 time: 1539688433
}];

З console.log() отримаємо не дуже зручний результат:

▶ (3) [{…}, {…}, {…}]

Якщо ви натиснете на стрілку, розгорнеться масив, але результат все одно не буде зрозумілим.

З console.table(data) усе по-іншому:

За межами console.log()

Другий необов'язковий аргумент — список стовпців. За замовчуванням виведуться усі стовпці, але можна зробити так:

> console.table(data, ["id", "price"]);

У результаті побачимо лише id та price. Корисно для занадто великих об'єктів з несуттєвими деталями. Стовпець index створюється автоматично.

За межами console.log()

Погляньте на стрілку у верхньому правому кутку. Якщо клікнути на неї, колонка відсортується за значенням price. Це дуже зручно, якщо треба знати мінімальне/максимальне значення або просто по-іншому оцінити дані. Ви можете скористатися такою можливістю і без зазначення конкретних стовпців.

console.table() може обробити максимум 1000 рядків, тому він не підійде для великих наборів даних.

console.assert()

Користь цієї функції часто недооцінюють. assert() — те ж саме, що й log(), але лише якщо перший аргумент приймає значення false. В іншому випадку, нічого не відбувається.

Функція стане у пригоді, якщо у вас є цикл (чи декілька різних викликів функцій) і лише один має конкретну поведінку. По суті, це те ж саме, що й:

if (object.whatever === 'value') {
  console.log(object);
}

Насправді, тут треба змінити умову на протилежну.

Припустимо, що одне зі значень у коді, що форматує дату null чи 0. Це призведе до помилки.

console.assert(tx.timestamp, tx);

Функція не виконується для усіх допустимих значень об'єкта. Але якщо timestamp отримає значення 0 чи null, одразу почнеться логування, тому що такі значення будуть false для нашого об'єкта.

Іноді не обійтися без більш складних умов. Наприклад, ми знайшли проблеми з даними у користувача WAL0412, і хочемо побачити операції лише з його даними.

console.assert(tx.buyer === 'WAL0412', tx);

Інтуїтивно вірно, але тут усе навпаки. Запам'ятайте, умова повинна повертати false. Це assert, а не filter.

console.assert(tx.buyer !== 'WAL0412', tx);

Тепер усе вірно.

console.assert() використовується не досить часто, але для деяких випадків вона може стати елегантним рішенням. Усі операції, що здійснювались не WAL0412, будуть істинними.

console.count()

Як зрозуміло з назви, ця функція є лічильником.

for(let i = 0; i < 10000; i++) {
  if(i % 2) {
    console.count('odds');
  }
  if(!(i % 5)) {
    console.count('multiplesOfFive');
  }
  if(isPrime(i)) {
    console.count('prime');
  }
}

Цей код не дуже корисний та трохи абстрактний. Просто уявіть, що функція isPrime працює.

По суті, ми отримаємо список:

odds: 1
odds: 2
prime: 1
odds: 3
multiplesOfFive: 1
prime: 2
odds: 4
prime: 3
odds: 5
multiplesOfFive: 2
...

І так далі. Функція стане у пригоді якщо ви скидали індекс або просто хочете запустити один чи декілька лічильників.

console.count() можна викликати без аргументів — за замовчуванням.

Для скидання лічильна можна використати console.countReset().

console.trace()

Роботу функції важко продемонструвати на невеликому фрагменті коду. Вона особливо корисна для випадків, коли ви хочете з'ясувати який саме виклик у класі чи бібліотеці призводить до помилки.

Наприклад, може бути 12 різних компонентів, які викликають сервіс, але в одного з них некоректно налаштована залежність.

export default class CupcakeService {
    
  constructor(dataLib) {
    this.dataLib = dataLib;
    if(typeof dataLib !== 'object') {
      console.log(dataLib);
      console.trace();
    }
  }
  ...
}

З console.log() ми дізнаємось лише що передається у dataLib, але не місце, в якому виникла помилка. Трасування стеку покаже нам, що проблема у Dashboard.js, а саме у new CupcakeService(false).

console.time()

Ця функція — найкращий спосіб відстежувати час виконання у JavaScript.

function slowFunction(number) {
  var functionTimerStart = new Date().getTime();
  // щось повільне чи складне з числами
  // на зразок факторіалів
  var functionTime = new Date().getTime() - functionTimerStart;
  console.log(`Function time: ${ functionTime }`);
}
var start = new Date().getTime();

for (i = 0; i < 100000; ++i) {
  slowFunction(i);
}

var time = new Date().getTime() - start;
console.log(`Execution time: ${ time }`);

Тут старий звичний спосіб. Зверніть увагу на console.log() вище. Ви можете не здогадуватись, що тут можна використовувати шаблонні рядки та інтерполяцію. Час від часу це допомагає.

Модернізуємо наш код.

const slowFunction = number =>  {
  console.time('slowFunction');
// щось повільне чи складне з числами
  // на зразок факторіалів
  console.timeEnd('slowFunction');
}
console.time();

for (i = 0; i < 100000; ++i) {
  slowFunction(i);
}
console.timeEnd();

Тепер нам не потрібна математика та тимчасові змінні.

console.group()

Переходимо до найскладнішої функції виводу в консоль. console.group() дозволяє вам.... групувати елементи. Зокрема, використовувати вкладення. Ця функція корисна тим, що відображає структуру коду.

// глобальна область видимості
let number = 1;
console.group('OutsideLoop');
console.log(number);
console.group('Loop');
for (let i = 0; i < 5; i++) {
  number = i + number;
  console.log(number);
}
console.groupEnd();
console.log(number);
console.groupEnd();
console.log('All done now');

Знову досить грубий приклад. Ви можете побачити такий результат:

За межами console.log()

Так ми можемо побачити об'єднання.

class MyClass {
  constructor(dataAccess) {
    console.group('Constructor');
    console.log('Constructor executed');
    console.assert(typeof dataAccess === 'object', 
      'Potentially incorrect dataAccess object');
    this.initializeEvents();
    console.groupEnd();
  }
  initializeEvents() {
    console.group('events');
    console.log('Initialising events');
    console.groupEnd();
  }
}
let myClass = new MyClass(false);
За межами console.log()

Треба звернути увагу також на console.groupCollapsed. Вона має таку ж функціональність, як console.group, але блок результату за замовчуванням згорнутий. Корисно, якщо необхідно приховати великий блок несуттєвої інформації.

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 6.2K
Приєднався: 7 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація