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

小編推薦: Fundebug提供JS、微信小程序、微信小游戲,Node.js和Java錯誤監控。真的是一個很好用的錯誤監控服務,眾多大佬公司都在使用。

Fundebug經授權轉載,版權歸原作者所有。

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 結構的輸出:

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

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

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();
    // 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");

輸出如下:

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

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

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

選擇 DOM 元素

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

但是當你沒有引用 jQuery 時,你仍然可以在谷歌開發控制臺中進行同樣的操作。

(‘tagName’)(‘.class’) You can't use 'macro parameter character #' in math mode(‘#id’) and(‘.class #id’) 等效于document.querySelector(‘ ‘),這將返回 DOM 中與選擇器匹配的第一個元素。

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

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

將瀏覽器轉換為編輯器

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

你不再需要檢查元素并編輯 HTML。相反,進入開發人員控制臺并輸入以下內容:

document.body.contentEditable = true;

這將使內容可編輯。現在,你幾乎可以編輯 DOM 中的任何內容。

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

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

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

要找到特定事件的偵聽器,可以這樣做:

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

原文:

關于Fundebug

Fundebug專注于JavaScript、微信小程序、微信小游戲、支付寶小程序、React Native、Node.js和Java線上應用實時BUG監控。 自從2016年雙十一正式上線,Fundebug累計處理了10億+錯誤事件,付費客戶有陽光保險、荔枝FM、掌門1對1、核桃編程、微脈、青團社等眾多品牌企業。歡迎免費試用!

您可能感興趣的

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,143評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,553評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,620評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,416評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,940評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,170評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,709評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,597評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,029評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,407評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,663評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,403評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,746評論 2 370

推薦閱讀更多精彩內容

  • 概要 64學時 3.5學分 章節安排 電子商務網站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,235評論 0 3
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML標準。 注意:講述HT...
    kismetajun閱讀 27,552評論 1 45
  • 工廠模式類似于現實生活中的工廠可以產生大量相似的商品,去做同樣的事情,實現同樣的效果;這時候需要使用工廠模式。簡單...
    舟漁行舟閱讀 7,796評論 2 17
  • 單例模式 適用場景:可能會在場景中使用到對象,但只有一個實例,加載時并不主動創建,需要時才創建 最常見的單例模式,...
    Obeing閱讀 2,085評論 1 10
  • ??JavaScript 與 HTML 之間的交互是通過事件實現的。 ??事件,就是文檔或瀏覽器窗口中發生的一些特...
    霜天曉閱讀 3,516評論 1 11