console 讓 js 調試更簡單

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 表示小數或整數。

另一個有趣的是 %c,這可能與你所想不太相同,它實際上是CSS值的佔位符。使用%c佔位符時,對應的後面的參數必須是CSS語句,用來對輸出內容進行CSS渲染。常見的輸出方式有兩種:文字樣式、圖片輸出

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

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

它有用嗎? 恩恩恩。

console.dir()

在大多數情況下,console.dir() 的函數非常類似於 log(),儘管它看起來略有不同。

下拉小箭頭將顯示與上面相同的對象詳細信息,這也可以從console.log 版本中看到。當你查看元素的結構時候,你會發現它們之間的差異更大,也更有趣。

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

使用 console.log 查看:

打開了一些元素,這清楚地顯示了 DOM,我們可以在其中導航。但是console.dir(element)給出了更加方便查看 DOM 結構的輸出。這是一種更客觀地看待元素的方式。有時候,這可能是您真正想要的,更像是檢查元素。

console.warn()

可能是最明顯的直接替換 log(),你可以以完全相同的方式使用 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.table(data, ["id", "price"]);

這裏要注意的是這是亂序的 - 最右邊的列標題上的箭頭顯示了原因。 我點擊該列進行排序。 找到列的最大或最小,或者只是對數據進行不同的查看非常方便。 順便說一句,該功能與僅顯示一些列無關,它總是可用的。console.table() 只能處理最多1000行,因此它可能不適合所有數據集。

console.assert()

assert()log() 是相同的函數,assert()是對輸入的表達式進行斷言,只有表達式爲false時,才輸出相應的信息到控制檯,示例如下:

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

有時我們需要更復雜的條件句。例如,我們已經看到了用戶 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');

輸出如下:

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

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);

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

文章轉自 前端小智,如有侵權,聯繫小編刪除。

喜歡你就點個贊。看完文章,還有福利拿,往下看👇👇👇
感興趣的小夥伴可以在公號【grain先森】後臺回覆【190414】獲取7張html、css思維導圖,也可以轉發朋友圈和你的朋友分享哦。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章