[譯] 前端 Console 除錯小技巧

lsvih發表於2017-11-12

前端 Console 除錯小技巧

開發者們在開發的過程中會無意地產生一些 bug。bug 越老,找到並修復它的難度就越高。在本系列的文章中,我將試著向你展示如何使用 Google Chrome 開發者工具、Chrome 外掛以及 WebStorm 進行除錯。

這篇文章將介紹最常用的除錯工具 —— Chrome Console。請享用!

Console

開啟 Chrome 開發者工具的方法:

  • 在主選單中選擇“更多工具”選單 > 點選開發者工具。
  • 在頁面任何元素上右鍵,選擇“檢查”。
  • 在 Mac 中,按下 Command+Option+I;在 Windows 與 Linux 中,按下 Ctrl+Shift+I。

請觀察 Console 選項卡中的內容。

第一行:

  • 清空 console 控制檯

top — 在預設狀態下,Console 的上下文(context)為 top(頂級)。不過當你檢查元素或使用 Chrome 外掛上下文時,它會發生變化。
你可以在此更改 console 執行的上下文(頁面的頂級 frame)。

過濾:
對控制檯的輸出進行過濾。你可以根據輸出嚴重級別、正規表示式對其進行過濾,也可以在此隱藏網路連線產生的訊息。

設定:
Hide network — 隱藏諸如 404 之類的網路錯誤。
Preserve log — 控制檯將會在頁面重新整理或者跳轉時不清空記錄。
Selected context only — 勾上後可以根據前面 top 選擇的上下文來指定控制檯的日誌記錄範圍。
User messages only — 隱藏瀏覽器產生的訪問異常之類的警告。
Log XMLHttpRequests — 顧名思義,記錄 XMLHttpRequest 產生的資訊。
Show timestamps — 在控制檯中顯示時間戳資訊。
Autocomplete from history — Chrome 會記錄你曾經輸入過的命令,進行自動補全。

選擇合適的 Console API

控制檯會在你應用的上下文中執行你輸入的 JS 程式碼。你可以輕鬆地通過控制檯檢視全域性作用域中儲存的東西,也可以直接輸入並檢視錶達式的結果。例如:“null === 0”。

console.log — 物件引用

根據定義,console.log 將會在控制檯中列印輸出內容。除此之外,你還得知道,console.log 會對你展示的物件保持引用關係。請看下面的程式碼:

var fruits = [{one: 1}, {two: 2}, {three: 3}];
console.log('fruits before modification: ', fruits);
console.log('fruits before modification - stringed: ', JSON.stringify(fruits));
fruits.splice(1);
console.log('fruits after modification: ', fruits);
console.log('fruits after modification - stringed : ', JSON.stringify(fruits))複製程式碼

當除錯物件或陣列時,你需要注意這點。我們可以看到 fruits 陣列再被修改前包含 3 個物件,但之後發生了變化。如需要在特定時刻檢視結果,可以使用 JSON.stringify 來展示資訊。不過這種方法對於展示大物件來說並不方便。之後我們會介紹更好的解決方案。

console.log — 對物件屬性進行排序

JavaScript 是否能保證物件屬性的順序呢?

4.3.3 Object — ECMAScript 第三版 (1999)

物件是 Object 的成員,它是一組無序屬性的集合,每個屬性都包含一個原始值、物件或函式。稱儲存在物件屬性中的函式為方法。

但是…… 在 ES5 中它的定義發生了改變,屬性可以有序 —— 但你還是不能確定你的物件屬性是否能按順序排列。瀏覽器通過各種方法實現了有序屬性。在 Chrome 中執行下面的程式碼,可以看到令人困惑的結果:

var letters = {
  z: 1,
  t: 2,
  k: 6
};
console.log('fruits', letters);
console.log('fruits - stringify', JSON.stringify(letters));複製程式碼

Chrome 按照字母表的順序對屬性進行了排序。沒法說我們是否應該喜歡這種排序方式,但瞭解這兒發生了什麼總沒壞處。

console.assert(expression, message)

如果 expression 表示式的結果為 falseConsole.assert 將會丟擲錯誤。關鍵的是,assert 函式不會由於報錯而停止評估之後的程式碼。它可以幫助你除錯冗長棘手的程式碼,或者找到多次迭代後函式自身產生的錯誤。

function callAssert(a,b) {
  console.assert(a === b, 'message: a !== b ***** a: ' + a +' b:' +b);
}
callAssert(5,6);
callAssert(1,1);複製程式碼

console.count(label)

簡而言之,它就是一個會計算相同表示式執行過多少次的 console.log。其它的都一樣。

for(var i =0; i <=3; i++){
    console.count(i + ' Can I go with you?');
    console.count('No, no this time');
}複製程式碼

如上面的例子所述,只有完全相同的表示式才會增加統計數字。

console.table()

很好用的除錯函式,但即使它會提高工作效率,我也一般懶得用它…… 別像我這樣,我們要保持高效。

var fruits = [
  { name: 'apple', like: true },
  { name: 'pear', like: true },
  { name: 'plum', like: false },
];
console.table(fruits);複製程式碼

它非常棒。第一,你可以將所有東西都整齊地放在表格中;第二,你也會得到 console.log 的結果。它在 Chrome 中可以正常工作,但是不保證相容所有瀏覽器。

var fruits = [
  { name: 'apple', like: true },
  { name: 'pear', like: true },
  { name: 'plum', like: false },
];
console.table(fruits, ['name'])複製程式碼

我們可以決定是完全展示資料內容還是隻展示整個物件的某幾列。這個表格是可排序的 —— 點選需要排序的列的表頭,即可按此列對錶格進行排序。

console.group() / console.groupEnd();

這次讓我們直接從程式碼開始介紹。執行下面的程式碼看看控制檯是如何進行分組的。

console.log('iteration');
for(var firstLevel = 0; firstLevel<2; firstLevel++){
  console.group('First level: ', firstLevel);
  for(var secondLevel = 0; secondLevel<2; secondLevel++){
    console.group('Second level: ', secondLevel);
    for(var thirdLevel = 0; thirdLevel<2; thirdLevel++){
      console.log('This is third level number: ', thirdLevel);
    }
    console.groupEnd();
  }
  console.groupEnd();
}複製程式碼

它可以幫助你更好的處理資料。

console.trace();

console.trace 會將呼叫棧列印在控制檯中。如果你正在構建庫或框架時,它給出的資訊將十分有用。

function func1() {
  func2();
}
function func2() {
  func3();
}
function func3() {
  console.trace();
}
func1();複製程式碼

對比 console.log 與 console.dir

console.log([1,2]);
console.dir([1,2]);複製程式碼

它們的實現方式取決於瀏覽器。在最開始的時候,規範中建議 dir 要保持對物件的引用,而 log 不需要引用。(Log 會顯示一個物件的副本)。但現在,如上圖所示,log 也保持了對於物件的引用。它們展示物件的方式有所不同,但我們不再加以深究。不過 dir 在除錯 HTML 物件的時候會非常有用。

譯註:console.dir 會詳細列印一個物件的所有屬性與方法。

$_, $0 — $4

$_ 會返回最近執行表示式的值。
$0 — $4 — 分別作為近 5 此檢查元素時對 HTML 元素的引用。

getEventListeners(object)

返回指定 DOM 元素上註冊的事件監聽器。這兒還有一種更便捷的方法來設定事件監聽,下次教程會介紹它。

monitorEvents(DOMElement, [events]) / unmonitorEvents(DOMElement)

在指定 DOM 元素上觸發任何事件時,都可以在控制檯中看到相關資訊。直到取消對相應元素的監視。

在控制檯中選擇元素

在 Element 標籤中按 ESC 鍵展開這個介面。

$ 沒有另做它用的情況下:

$() — 相當於 **document.querySelector()**。它會返回匹配 CSS 選擇器的第一個元素(例如 $('span') 會返回第一個 span)
$$() — 相當於 **document.querySelectorAll()**。它會以陣列的形式返回所有匹配 CSS 選擇器的元素。

複製列印的資料

有時,當你處理資料時可能會想打個草稿,或者簡單地看看兩個物件是否有區別。全選之後再複製可能會很麻煩,在此介紹一種很方便的方法。

在列印出的物件上點選右鍵,選擇 copy(複製),或選擇 Store as global element(將指定元素的引用儲存在全域性作用域中),然後你就可以在控制檯中操作剛才儲存的元素啦。

控制檯中的任何內容都可以通過使用 copy('object-name') 進行復制。

自定義控制檯輸出樣式

假設你正在開發一個庫,或者在為公司、團隊開發一個大模組。此時在開發模式下對一些日誌進行高亮處理會很舒爽。你可以試試下面的程式碼:

console.log('%c Truly hackers code! ', 'background: #222; color: #bada55');

%d%i — 整型值
%f — 浮點值
%o — 可展開的 DOM 元素
%O — 可展開的 JS 物件
%c — 使用 CSS 格式化輸出

以上就是本文的全部內容,但並不是 Console 這個話題的全部內容。你可以點選以下連結瞭解更多有關知識:


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOSReact前端後端產品設計 等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章