靈活使用 console 讓 js 調試更簡單

阿里雲最近在作活動,低至2折,有興趣能夠看看:
https://promotion.aliyun.com/...

爲了保證的可讀性,本文采用意譯而非直譯。javascript

Web開發最經常使用的高度就是 console.log ,雖然 console.log 佔有一席之地,但不少人並無意識到 console 自己除了基本 log 方法以外還有不少其餘方法。 適當使用這些方法可使調試更容易,更快速,更直觀。html

想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等着你!前端

console.log()

console.log 中有不少人們意想不到的功能。雖然大多數人使用 console.log(object) 來查看對象,可是你也可使用 console.log(object, otherObject, string),它會把它們都整齊地記錄下來,偶爾也會很方便。java

不只如此,還有另外一種格式化的: console.log(msg, values),這很像 C 或 PHP 中的sprintfgit

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

會像你預期的那樣輸出:github

> I like Skittles but I do not like pus.

常見的佔位符 %o (這是字母o,不是0),它接受對象,%s 接受字符串,%d 表示小數或整數。segmentfault

圖片描述

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

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

clipboard.png

它並不優雅,也不是特別有用。固然,這並非一個真正的按鈕。瀏覽器

clipboard.png

它有用嗎? 恩恩恩。編輯器

console.dir()

在大多數狀況下,console.dir() 的函數很是相似於 log(),儘管它看起來略有不一樣。

clipboard.png

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

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

使用 console.log 查看:

clipboard.png

打開了一些元素,這清楚地顯示了 DOM,咱們能夠在其中導航。可是console.dir(element)給出了更加方便查看 DOM 結構的輸出:

這是一種更客觀地看待元素的方式。有時候,這多是您真正想要的,更像是檢查元素。

clipboard.png

console.warn()

多是最明顯的直接替換 log(),你能夠以徹底相同的方式使用 console.warn()。 惟一真正的區別是輸出字的顏色是黃色的。 具體來講,輸出處於警告級別而不是信息級別,所以瀏覽器將稍微區別對待它。 這具備使其在雜亂輸出中更明顯的效果。

clipboard.png

不過,還有一個更大的優點,由於輸出是警告而不是信息,因此你能夠過濾掉全部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) 的輸出要有用得多。

clipboard.png

第二個可選參數是所需列的列表。顯然,全部列都是默認值,但咱們也能夠這樣作:

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

clipboard.png

這裏要注意的是這是亂序的 - 最右邊的列標題上的箭頭顯示了緣由。 我點擊該列進行排序。 找到列的最大或最小,或者只是對數據進行不一樣的查看很是方便。 順便說一句,該功能與僅顯示一些列無關,它老是可用的。

console.table() 只能處理最多1000行,所以它可能不適合全部數據集。

console.assert()

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

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

clipboard.png

有時咱們須要更復雜的條件句。例如,咱們已經看到了用戶 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();
  // something slow or complex with the numbers. 
  // Factorials, or whatever.
  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');
  // something slow or complex with the numbers. 
  // Factorials, or whatever.
  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');

輸出以下:

clipboard.png

並非頗有用,可是您能夠看到其中一些是如何組合的。

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

clipboard.png

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

選擇DOM元素

若是熟悉jQuery,就會知道 $(‘.class’)$(‘#id’) 選擇器有多麼重要。它們根據與之關聯的類或 ID 選擇 DOM 元素。

可是當你沒有引用 jQuery時,你仍然能夠在谷歌開發控制檯中進行一樣的操做。

$(‘tagName’) $(‘.class’) $(‘#id’) and $(‘.class #id’) 等效於document.querySelector(‘ ‘),這將返回 DOM 中與選擇器匹配的第一個元素。

可使用 \$\$(tagName)\$\$(.class), 注意雙元符號,根據特定的選擇器選擇DOM的全部元素。這也將它們放入數組中,你也能夠經過指定數組中該元素的位置來從中選擇特定的元素。

例如,&dollar;&dollar;(‘.className’) 獲取具備類 className 的全部元素,而\$\$(‘.className’)[0]\$\$(‘.className’)[1]獲取到分別是第一個和第二個元素。

clipboard.png

將瀏覽器轉換爲編輯器

你有多少次想知道你是否能夠在瀏覽器中編輯一些文本? 答案是確定的,你能夠將瀏覽器轉換爲文本編輯器。 你能夠在 DOM 中的任何位置添加文本和從中刪除文本。

你再也不須要檢查元素並編輯HTML。相反,進入開發人員控制檯並輸入如下內容:

document.body.contentEditable=true

這將使內容可編輯。如今,你幾乎能夠編輯DOM中的任何內容。

查找與DOM中的元素關聯的事件

調試時,須要查找 DOM 中某個元素的事件偵聽器感時,谷歌控制檯了 getEventListeners使找到這些事件更加容易且直觀。

getEventListeners($(‘selector’)) 返回一個對象數組,其中包含綁定到該元素的全部事件。你能夠展開對象來查看事件:

clipboard.png

要找到特定事件的偵聽器,能夠這樣作:

getEventListeners($(‘selector’)).eventName[0].listener

這將顯示與特定事件關聯的偵聽器。這裏 eventName[0] 是一個數組,它列出了特定事件的全部事件。例如:

getEventListeners($(‘firstName’)).click[0].listener

將顯示與 ID 爲 ‘firstName’ 的元素的單擊事件關聯的偵聽器。

監控事件

若是但願在執行綁定到 DOM 中特定元素的事件時監視它們,也能夠在控制檯中這樣作。你可使用不一樣的命令來監控其中的一些或全部事件:

若是但願在執行綁定到DOM中特定元素的事件時監視它們,也能夠在控制檯中這樣作。你可使用不一樣的命令來監控其中的一些或全部事件:

  • monitorEvents($(‘selector’)) 將監視與選擇器的元素關聯的全部事件,而後在它們被觸發時將它們打印到控制檯。例如,monitore($(#firstName)) 將打印 IDfirstName元素的全部事件。
  • monitorEvents($(‘selector’),’eventName’) 將打印與元素綁定的特定事件。 你能夠將事件名稱做爲參數傳遞給函數。 這將僅記錄綁定到特定元素的特定事件。 例如,monitorEvents($(‘#firstName’),’click’) 將打印綁定到ID爲'firstName'的元素的全部 click 事件。
  • monitore($(selector),[eventName1, eventName3', .])將根據您本身的需求記錄多個事件。與其傳遞單個事件名做爲參數,不如傳遞包含全部事件的字符串數組。例如monitore($(#firstName),[click, focus])將記錄與ID firstName元素綁定的 click事件和focus事件。
  • unmonitorevent ($(selector)):這將中止監視和打印控制檯中的事件。

檢查 DOM 中的一個元素

你能夠直接從控制檯檢查一個元素:

  • inspect($(‘selector’)) 將檢查與選擇器匹配的元素,並轉到 Chrome Developer Tools中的 Elements 選項卡。 例如, inspect($(‘#firstName’)) 將檢查 ID爲'firstName' 的元素,spect($(‘a’)[3]) 將檢查 DOM 中的第 4 個 a 元素。
  • $0, $1, $2 等能夠幫助你獲取最近檢查過的元素。 例如,$0 表示最後檢查的 DOM 元素,而$1 倒數第二個檢查的 DOM 元素。

檢索最後一個結果的值

你能夠將控制檯用做計算器。當你這樣作的時候,你可能須要用第二個來跟蹤一個計算。如下是如何從內存中檢索先前計算的結果:

$_

過程以下:

2+3+4
9 //- The Answer of the SUM is 9

$_
9 // Gives the last Result

$_ * $_
81  // As the last Result was 9

Math.sqrt($_)
9 // As the last Result was 81

$_
9 // As the Last Result is 9

清除控制檯和內存

若是你想清除控制檯及其內存,輸入以下:

clear()

代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug


原文:
https://medium.com/@mattburge...

https://medium.freecodecamp.o...

你的點贊是我持續分享好東西的動力,歡迎點贊!

交流

乾貨系列文章彙總以下,以爲不錯點個Star,歡迎 加羣 互相學習。

https://github.com/qq44924588...

我是小智,公衆號「大遷世界」做者,對前端技術保持學習愛好者。我會常常分享本身所學所看的乾貨,在進階的路上,共勉!

關注公衆號,後臺回覆福利,便可看到福利,你懂的。

clipboard.png

相關文章
相關標籤/搜索