天天看點

console 讓 js 調試更簡單console.log()console.dir()console.warn()console.table()console.assert()console.count()console.trace()console.time()console.group()

Web開發最常用的就是

console.log

,雖然

console.log

占有一席之地,但很多人并沒有意識到

console

本身除了基本

log

方法之外還有很多其他方法。 适當使用這些方法可以使調試更容易,更快速,更直覺。

console.log()

console.log

中有很多人們意想不到的功能。雖然大多數人使用

console.log(object)

來檢視對象,但是你也可以使用

console.log(object, otherObject, string)

,它會把它們都整齊地記錄下來,偶爾也會很友善。不僅如此,還有另一種格式化的:

console.log(msg, values)

,這很像 C 或 PHP 中的

sprintf

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

複制

會像你預期的那樣輸出:

> I like Skittles but I do not like pus.           

複制

常見的占位符

%o

(這是字母o,不是0),它接受對象,

%s

接受字元串,

%d

表示小數或整數。

console 讓 js 調試更簡單console.log()console.dir()console.warn()console.table()console.assert()console.count()console.trace()console.time()console.group()

常見的占位符

另一個有趣的是

%c

,這可能與你所想不太相同,它實際上是CSS值的占位符。使用%c占位符時,對應的後面的參數必須是CSS語句,用來對輸出内容進行CSS渲染。常見的輸出方式有兩種:

文字樣式、圖檔輸出

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

複制

console 讓 js 調試更簡單console.log()console.dir()console.warn()console.table()console.assert()console.count()console.trace()console.time()console.group()

CSS值占位符

它并不優雅,也不是特别有用。當然,這并不是一個真正的按鈕。

console 讓 js 調試更簡單console.log()console.dir()console.warn()console.table()console.assert()console.count()console.trace()console.time()console.group()

并不是一個真正的按鈕

它有用嗎? 恩恩恩。

console.dir()

在大多數情況下,

console.dir()

的函數非常類似于

log()

,盡管它看起來略有不同。

console 讓 js 調試更簡單console.log()console.dir()console.warn()console.table()console.assert()console.count()console.trace()console.time()console.group()

console.dir()

下拉小箭頭将顯示與上面相同的對象詳細資訊,這也可以從

console.log

版本中看到。當你檢視元素的結構時候,你會發現它們之間的差異更大,也更有趣。

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

複制

使用

console.log

檢視:

console 讓 js 調試更簡單console.log()console.dir()console.warn()console.table()console.assert()console.count()console.trace()console.time()console.group()

列印對象

打開了一些元素,這清楚地顯示了 DOM,我們可以在其中導航。但是

console.dir(element)

給出了更加友善檢視 DOM 結構的輸出。這是一種更客觀地看待元素的方式。有時候,這可能是您真正想要的,更像是檢查元素。

console 讓 js 調試更簡單console.log()console.dir()console.warn()console.table()console.assert()console.count()console.trace()console.time()console.group()

更像檢查元素

console.warn()

可能是最明顯的直接替換

log()

,你可以以完全相同的方式使用

console.warn()

。 唯一真正的差別是輸出字的顔色是黃色的。 具體來說,輸出處于警告級别而不是資訊級别,是以浏覽器将稍微差別對待它。 這具有使其在雜亂輸出中更明顯的效果。

console 讓 js 調試更簡單console.log()console.dir()console.warn()console.table()console.assert()console.count()console.trace()console.time()console.group()

console.warn()

不過,還有一個更大的優勢,因為輸出是警告而不是資訊,是以你可以過濾掉所有

console.log

并僅保留

console.warn

。 這對于偶爾會在浏覽器中輸出大量無用廢話的應用程式尤其有用。 清除一些無用的資訊可以讓你更輕松地看到你想要的輸出。

console.table()

令人驚訝的是,這并不是更為人所知,但是

console.table()

函數旨在以一種比僅僅轉出原始對象數組更整潔的方式顯示表格資料。例如,這裡有一個資料清單:

const data = [{
  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 讓 js 調試更簡單console.log()console.dir()console.warn()console.table()console.assert()console.count()console.trace()console.time()console.group()

console.table(data)

第二個可選參數是所需列的清單。顯然,所有列都是預設值,但我們也可以這樣做:

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

複制

console 讓 js 調試更簡單console.log()console.dir()console.warn()console.table()console.assert()console.count()console.trace()console.time()console.group()

帶參數的console.table

這裡要注意的是這是亂序的 - 最右邊的列标題上的箭頭顯示了原因。 我點選該列進行排序。 找到列的最大或最小,或者隻是對資料進行不同的檢視非常友善。 順便說一句,該功能與僅顯示一些列無關,它總是可用的。

console.table()

隻能處理最多1000行,是以它可能不适合所有資料集。

console.assert()

assert()

log()

是相同的函數,

assert()

是對輸入的表達式進行斷言,隻有表達式為false時,才輸出相應的資訊到控制台,示例如下:

var arr = [1, 2, 3];
console.assert(arr.length === 4);           

複制

console 讓 js 調試更簡單console.log()console.dir()console.warn()console.table()console.assert()console.count()console.trace()console.time()console.group()

console.assert()

有時我們需要更複雜的條件句。例如,我們已經看到了使用者

WAL0412

的資料問題,并希望僅顯示來自這些資料的事務,這是直覺的解決方案。

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

複制

這看起來不錯,但行不通。記住,條件必須為

false

,斷言才會執行,更改如下:

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

複制

與其中一些類似,

console.assert()

并不總是特别有用。但在特定的情況下,它可能是一個優雅的解決方案。

console.count()

另一個具有特殊用途的計數器,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.countReset()

,可以使用它重置計數器。

console.trace()

trace()

在簡單的資料中很難示範。當您試圖在類或庫中找出是哪個實際調用者導緻了這個問題時,它的優勢就顯現出來了。例如,可能有 12 個不同的元件調用一個服務,但是其中一個元件沒有正确地設定依賴項。

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

複制

這裡使用

console.log()

僅告訴我們傳遞資料

dataLib

是什麼 ,而沒有具體的傳遞的路徑。不過,

console.trace()

會非常清楚地告訴我們問題出在

Dashboard.js

,我們可以看到是

new CupcakeService(false)

導緻錯誤。

console.time()

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

來簡化以上代碼。

const slowFunction = number =>  {
  console.time('slowFunction');
  console.timeEnd('slowFunction');
}
console.time();
for (i = 0; i < 100000; ++i) {
  slowFunction(i);
}
console.timeEnd();           

複制

我們現在不再需要做任何計算或設定臨時變量。

console.group()

// this is the global scope
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 讓 js 調試更簡單console.log()console.dir()console.warn()console.table()console.assert()console.count()console.trace()console.time()console.group()

console.group

并不是很有用,但是您可以看到其中一些是如何組合的。

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 讓 js 調試更簡單console.log()console.dir()console.warn()console.table()console.assert()console.count()console.trace()console.time()console.group()

調試資訊的代碼

這是很多工作和很多調試資訊的代碼,可能不是那麼有用。 但它仍然是一個有趣的想法,這樣寫使你的日志記錄更加清晰。