【译】你可能不知道的14个JavaScript调试小技巧

原文地址: https://raygun.com/javascript-debugging-tips?utm_source=cooperpress&utm_medium=primary&utm_campaign=cooperpress-javascript

常言道:工欲善其事必先利其器。虽然 JavaScript 确实难以调试,但是如果你能多掌握一些调试相关的小技巧,那么在面对错误和 bug 的时候你将能更快的解决掉它们。

我们在这里列举了 14 个你可能还不知道,但确实行之有效的调试小技巧,希望你能在下次调试你的时候用到。

让我们开始吧!

这里提到的大多数技巧都是针对于 Chrome 和 Firefox 检查工具的,可能这些技巧在其他浏览器中也能使用。

  1. debugger
    debugger 是除了 console.log 外,我最喜欢也最常用的调试工具。当 debugger 出现在里的代码中,Chrome 会在执行到这里的时候自动的停下来。你还可以把 debugger 放在条件语句中,这样就可以只在你需要停止的地方停止。

    if (thisThing) {
      debugger;
    }
    
  2. Display objects as a table(用 table 来展示对象数据)
    有时你会想要在控制台下查看复杂对象组成的数组,你可以继续使用 console.log 打印出所有的数据,然后通过滚动滚动条来查看每一条数据,或者是时候给 console.table 一个机会了,它将会让数据更一目了然。

    var animals = [
      { animal: 'Horse', name: 'Henry', age: 43 },
      { animal: 'Dog', name: 'Fred', age: 13 },
      { animal: 'Cat', name: 'Frodo', age: 18 },
    ]
    console.table(animals);
    

    输出结果:

    console.table
  3. Try all the sizes(响应式布局)
    如果你能拥有所有不同尺寸的移动设备会不会很酷,然而这在现实中却是不现实的(译者注:调试起来也是够麻烦的吧)。既然无法拥有所有尺寸的设备,那我们能不能通过修改视口(viewport)大小 来模拟任意尺寸的设备呢?很显然 Chrome 浏览器的开发人员也想到了这一点,点击调试工具的 toggle device mode(切换设备模式)按钮打开新世界,看看你的响应式布局是不是写的贼溜。

    media querys
  4. How to find your DOM elements quickly(在控制台中快速选定你要的 DOM 元素)
    在 Elements 面板中选中一个节点,你可以直接在 console 命令行中直接找到这个节点,而不需要再进行 dom 查找。Chrome 调试工具会自动的记录最近选中的 5 个 DOM 节点,在控制台下分别通过 $0$1$2$3$4 访问。

    对于下面的 DOM 结构,如果你依次选中 item-4item-3item-2item-1item-0,你可以通过 $0-4 快速的在 console 命令行中使用这些节点。

    $
  5. Benchmark loops using console.time() and console.timeEnd() (使用 console.time 来衡量执行耗时)
    如果能够确切的知道一段代码执行花费了多长的时间,尤其是对于比较慢的循环,这对我们代码的调优将会很有用。使用 console.time 你甚至可以通过在调用 console.time 的时候传入 不同的 label(关键字)记录不同的代码运行所花的时间。

    console.time('Timer1');
    var items = [];
    for(var i = 0; i < 100000; i++){
       items.push({index: i});
    }
    console.timeEnd('Timer1');
    

    上面的代码会输出以下内容:


    console.time
  6. Get the stack trace for a function(跟踪方法调用链)
    在进行 JavaScript 相关开发的时候我们肯定会用到一些框架来构建我们的页面,处理相关事件。由于 JavaScript 是非结构化语言,有时候将很难知道在 什么时候 发生了 什么事情 。这个时候我们就可以使用 console.trace 来快速找到一个函数的调用链帮助我们调试了。

    举个例子,我们希望能够跟踪到第 33 行 car 实例的 funcZ 是通过怎样的调用链被调用的。

    var car;
    var func1 = function() {
        func2();
    }
    
    var func2 = function() {
        func4();
    }
    var func3 = function() {
    }
    
    var func4 = function() {
        car = new Car();
        car.funcX();
    }
    var Car = function() {
        this.brand = 'volvo';
        this.color = 'red';
        this.funcX = function() {
            this.funcY();
        }
    
        this.funcY = function() {
            this.funcZ();
        }
    
        this.funcZ = function() {
            console.trace('trace car')
        }
    }
    func1();
    

    上面的代码输出如下:

    console.trace

    通过输出我们可以明确的看到 car.funcZ 是通过 func1 调用 func2, func2 调用 func4,在 func4 中新建 Car 的实例,然后调用 car.funcX,最后在 car.funcX 中调用 car.funxY,在 car.funcY 中调用 car.funcZ 这样一个调用链被触发的。

    尽管你会觉得我的代码是我完全可控的,我很清楚函数都是如何调用的,但请相信 console.trace 真的很好用。假设我们现在想要优化一下代码,你只需要在相应的方法里面添加上 console.trace,然后就能明确的看到该方法是如何被触发的。等等,console.trace 输出的结果还是可点击的,你可以通过点击直接跳转到对应的代码位置,所以除了展示调用链我们还多了个额外的目录。

  7. Unminify code as an easy way to debug JavaScript(格式化压缩过后的 JavaScript 代码)
    线上的代码通常都是压缩过的,而且 sourceMap 文件也不会在线上服务被使用,这可怎么调试线上代码呢?

    不要怕,有问题找工具,Chrome 可以对 JavaScript 代码进行格式化,将其变成可读的。虽然比不上源代码的可读性,但至少你能看出代码是如何运行的。要格式化一个 JavaScript 文件,只需要点击 Sources 面板下方的 {} 按钮

    pretty code
  8. Quick-find a function to debug(快速开始方法的调试)
    当我们想要调试一个方法的时候,最常用的添加断点的方法是:

    1. 在 source 面板中找到对应方法所在行,添加一个断点
    2. 在代码中添加 debugger

    不管采用上面那种方法设置断点,你都需要在代码中找到特定的行才能添加断点,这可能并不那么容易。

    其实在 console 命令行中使用 debug(funcName) 就能快速的添加对于对应函数的断点,一旦这个函数开始执行的时候就会像添加了 debugger 一样在这里暂停下来。

    这样会比前面两种方法更快的添加断点,要说有什么不好的就是使用这种方法对匿名函数不适用。只要不是匿名函数的情况,这将会是最快的开始一个方法调试的途径。

    注意 console.debugdebug(funcName) 并不是同一回事。

    var func1 = function() {
      func2();
    }
    var Car = function () {
      this.funcX = function() {
        this.funcY();
      }
      this.funcY = function() {
        this.funcZ();
      }
    }
    var car = new Car();
    

    在控制台下输入 debug(car.funcY),在控制台打开的情况下如果脚本运行到 car.funcY 这个方法的时候就会暂停下来。

    debug
  9. Black box scripts that NOT relevant(跳过不相关代码的断点)
    日常开发中我们经常会使用到很多第三方的Js库,这些 Js 库文件都是经过很好的测试过的,通常可以认为这些代码是没有 bug 的,按说应该可以跳过调试断点的。但是实际上浏览器并不区分这些代码,代码运行时如果这些代码里面存在断点,断点依然会在这里暂停下来,这会打断我们的调试工作。解决方案就是把这些不需要调试的代码(包括你自己的代码)添加到 black box 里面,跳过里面的所有断点。更多相关内容请查看这里

  10. Find the important things in complex debugging(快速抓住重点)
    在一些复杂的场景下我们可能会在控制台下输出很多的内容,良好的输出格式帮助我们更好的找到关键点。做到这一点我们可以使用 console.log, console.debug, console.debug, console.warn, console.infoconsole.error 等方法输出不同格式的日志,然后通过筛选器就能过滤出我们所关心的日志内容。但有时候这并不是你所想要的调试方法,这样的输出并不突出,为了更好的突出重点内容,你可以在控制台下使用 CSS 来装饰你的输出内容,这会更好的突出内容,帮助你快速抓住重点。

    console.todo = function(msg) {
      console.log('%c%s%s%s', 'color: yellow; background-color: black', '-', msg, '-');
    }
    console.important = function(msg) {
      console.log('%c%s%s%s', 'color: brown; font-weight: bold; text-decoration: underline;', '-', msg, '-');
    console.todo('This is something that\'s need to be fixed');
    console.important('This is an important message');
    }
    

    输出内容如下:

    console

    在使用 console.log 的时候,我们可以使用 %s 来作为字符串的占位符,%i 作为数字的占位符,还可以使用 %c 来使用自定义样式。你可以以任意你能想象到的样式来使用它们,比如在调试一个单页应用的时候,我们可以对于不同模型的日志(model, controller)输出为不同的样式,方便快速定位不同模块的日志输出。除此之外你还可以为这些方法定义更简短的方法名,方便调用。

  11. Watch specific function calls and its arguments
    在 Chrome 的控制台下,我们可以完全地监听特定方法的调用,一旦添加了特定方法的监听,每当这个方法被调用的时候都会在控制台下打印出调用时传入的参数。

    var func1 = function(x, y, z) {
      // ...
    }
    monitor(func1);
    func1(1, 2);
    
    monitor
  12. Quickly access elements in the console(快速在控制台下选择元素)
    在控制台下我们可以方便的使用 $('css-selector') 符来实现
    querySelector 的功能,使用 $$('css-selector') 来实现 querySelectorAll 的功能。如果你需要多次访问同一个 DOM 元素,将这个元素保存到一个变量里面是很实用的。

    $$
  13. Postman is great(but Firefox is faster)
    很多开发者都会使用 Postman 工具来调试 ajax 相关内容。虽然 Postman 确实很好用,但是强迫症表示要重开一个浏览器窗口然后手动新建一个请求才能测试有点不能接受。
    比起使用 Postman 工具,有时候你的浏览器在处理 ajax 相关内容的时候会更快。
    当你使用浏览器默认的网络面板来进行 ajax 调试的时候,还能保留用户的登录信息不需要再手动去请求里面添加 cookie 等信息,在 Firefox 下你甚至可以对一些请求直接进行编辑然后重发。
    如何来实现呢?只需要打开开发工具,切换到 network 面板,找到你想要编辑的请求记录,右击选择 Edit and Resend 然后就可以随意的修改添加任何你想要的参数了,点击 resend 就能按照你修改后的请求发送了。

    image.png

  14. Break on node change(在DOM节点变化的时候break)
    DOM 操作是一件有趣的事,但是对于调试而言有时看到 DOM 发生的变化,但是我们并不知道变化是如何发生的,这就非常难调试了。好在 Chrome 给我们提供了 DOM 变化时的 debugger 工具(译者注:暂停的效果和 JavaScript debugger 类似)。开启一个 DOM 的变化监听,只需要在 Element 面板中选择一个 DOM元素 然后右键在最下面的 Break on 菜单的子目录下选择一种断点方式就可以了。

    Break on node change

    可选的断点方式:子节点变化,自身属性变化,移除node。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容