浅析JavaScript 调试方法和技巧


Posted in Javascript onOctober 22, 2015

javascript简称JS,是网页的前端开发语言,直接运行在浏览器上,以前我刚开始学的时候,并不懂这个,所以我每次开发或调试它,都是在vs.net里面,现在想想,实在是太痛苦了,其实JS是执行在浏览器的,而不是执行在服务器的,所以根本没必要在网页开发软件里搞,直接在浏览器中即可调试

浏览器开发者工具

我个人最喜欢Chrome开发者工具。 虽然Safari和Firefox无法达到Chrome那么高的标准,但它们也在逐渐改善。在Firefox中,可以将Firebug和Firefox开发者工具组合使用。如果Firefox小组在改进内置开发者工具方面继续表现优异的话,Firebug有一天可能会被淘汰。

先把个人偏好放在一边,你应该能够在目标浏览器中对任意代码进行试验和调试。你的目标浏览器可能包括著名的IE8,也可能不包括。

要熟悉你自己选择的开发者工具。你还可以从IDE(集成开发环境)或者第三方软件获得额外的调试支持。

在各种调试工具中,调试的基础知识是相通的。事实上,我是在90年代从Borland的C开发者环境中学习的调试基础。断点、条件 断点、监视与最新版Chrome开发者工具是完全相同的。2000年左右,我在Java中捕获到第一例异常。堆栈跟踪(Stack traces)的概念依然适用,即使J avaScript术语将其称作错误(Error),检查堆栈跟踪仍然和以前一样有用。

有些知识点是前端开发特有的。例如:

DOM检查
DOM断点
调试事件
内存泄露分析
断点

使用 debugger 语句可以在源代码中增加断点。一旦到达 debugger 语句,执行中断。当前作用域的上下文出现在控制台中,还有所有的局部变量和全局变量。将鼠标光标移到变量上可以查看变量的值。

在代码中还可以创建条件断点:

JavaScript

if (condition) {
  debugger;
}

还可以 根据自己需要 在开发者工具中插入断点和条件断点。在Chrome开发者工具中,在Sources视图中点击行号即可增加断点。如果在断点上点击右键并选择“编辑断点(Edit Breakpoint)”,你还可以增加断点条件。

节点变化的断点

如果你的任务是调试垃圾代码,你 可能会有这样的问题: 为什么DOM节点在执行过程中发生了改变。Chrome开发者工具提供了一种方便的断点,可用来 检测 元素树中的节点变化。

在Elements视图中,右键 点击 一个元素,从右键菜单中选择“Break on…”。

 浅析JavaScript 调试方法和技巧

DOM断点的类型可能包括:

选定节点树状子目录 (sub-tree) 中的节点变化,
选定节点的属性发生变化,
节点被删除。

避免记录引用类型

当记录对象或数组时, 原始类型的值在引用对象记录中可能会发生变化。当查看引用类型时一定要记住,在记录和查看期间,代码执行可能会影响观测到的结果 。

例如,在Chrome开发者工具中执行以下代码:

JavaScript

var wallets = [{ amount: 0 }];
setInterval( function() {
  console.log( wallets, wallets[0], wallets[0].amount );
  wallets[0].amount += 100;
}, 1000 );

记录的第二个和第三个属 性的值是正确的,第一个属性中对象引用的值是不可靠的。当你第一次在开发者工具中显示这个属性时,amount域的值就已经确定了。无论你对同一个引用关 闭并重新打开多少次,这个值都不会变化。

 浅析JavaScript 调试方法和技巧

记录参考类型

永远记得你在记录什么。记录原始类型时,使用带断点的watch表达式。如果是异步代码,避免记录 引用类型 。

表格记录

在一些开发者工具中,你可以用 console.table 在控制台中记录对象数组。

尝试在你的Chrome开发者工具中执行下列代码:

JavaScript

console.table(
  [
    { 
      id: 1, 
      name: 'John', 
      address: 'Bay street 1'
    }, 
    {
      id: 2, 
      name: 'Jack', 
      address: 'Valley road 2.'
    }, 
    {
      id: 3, 
      name: 'Jim', 
      address: 'Hill street 3.' 
    }
  ] );

输出是非常好看的表格。所有原始类型都立刻显示出来,它们的值反应记录时的状态。也可以记录复杂类型,显示内容为其类型,内容无法显示。因此, console.table 只能用来显示具有原始类型值的对象构成的二维数据结构。

XHR断点

有时你可能会遇到错误的AJAX请求。如果你无法立刻确认提交请求的代码,XHR断点可以帮你节省时间。当提交某一特殊类型的AJAX时,XHR断点将会终止代码的执行,并将提交请求的代码段呈现给用户。

在Chrome开发者工具的Sources标签页中,其中一个断点类型就是XHR断点。点击 + 图标,你可以输入URL片段,当AJAX请求的URL中出现这个URL片段时,JavaScript代码将会中断。

事件监听器断点

Chrome开发者工具可以捕获所有类型的事件,当用户按下一个键、点击一下鼠标时,可以对触发的事件进行调试。

异常时暂停

Chrome开发者工具可以在抛出异常时暂停 执行 JavaScript代码。这可以让你在Error对象被创建时观察应用的状态。

 浅析JavaScript 调试方法和技巧

异常时暂停

Sources标签页左侧面板上有一个代码片段(Snippet)子标签页,可用于保存代码片段,帮你调试代码。

如果你坚持使用控制台调试,反复写相同的代码,你应该将你的代码抽象成调试片段。这样的话,甚至还可以把你的调试 技巧教给你 的同事。

Paul Irish发布过一些基本的 调试代码片段 ,例如在函数执行前插入断点。审查这些代码片段,并在网上搜索其他代码片段,这是 很有价值的 。

在函数执行前插入断点

如果你可以得到函数调用的源代码,你还可以在函数调用前插入断点来终止函数的执行。如果你想调试 f 函数,用 debug(f) 语句可以增加这种断点。

Unminify最小化代码

( 译者注:unminify 解压缩并进行反混淆 )

尽可能使用 source map。有时生产代码 不能使用 source map,但不管怎样,你都  不应该直接对生产代码进行调试 。

(译者注:sourcemap 是针对压缩合并后的web代码进行调试的工具)

如果没有source map的话,你最后还可以求助于Chrome开发者工具Sources标签页中的格式化按钮(Pretty Print Button)。格式化按钮 {} 位于源代码文本区域的下方。格式化按钮对源代码进行美化,并改变行号,这使得调试代码更加方便,堆栈跟踪更加有效。

格式化按钮只有在不得已时才会使用。从某种意义上来说, 丑代码就是难看,因为代码中的命名没有明确的语义 。

DOM元素的控制台书签

Chrome开发者工具和Firebug都提供了书签功能,用于显示你在元素标签页(Chrome)或HTML标签页(Firebug)中最后点击的DOM元素。如果你依次选择了 A 元素、 B 元素和 C 元素,

$0   表示 C 元素
$1 表示 B 元素
$2 表示 A 元素

如果你又选择了元素 D ,那么 $0 、 $1 、 $2 和 $3 分别代表 D 、 C 、 B 和 A 。

访问调用栈

JavaScript

var f = function() { g(); } 
var g = function() { h(); }
var h = function() { console.trace('trace in h'); }
f();

Chrome开发者工具中的Sources标签页也在Watch表达式下面显示调用栈。

性能审查

性能 审查 工具通常是很有用的。这些工具可以用于防止内存泄露,还可以检测到你的网站哪里需要优化。由于这些工具并不了解你的产品,你可以忽略其某些建议。通常来说,性能分析工具能够有效范围,可以使你的网站显著优化。

审查工具举例:

Chrome开发者工具的Audit标签页
YSlow

熟能生巧

你可能熟悉某些调试技巧,其他 技巧 也会帮你节省不少时间。如果你开始在实践中使用这些技巧,我建议你几周之后重新阅读本文。你将会惊奇地发现,你的关注点在几周内就发生了变化。

Javascript 相关文章推荐
javascript重写alert方法的实例代码
Mar 29 Javascript
AngularJS基础知识笔记之表格
May 10 Javascript
js判断当前页面在移动设备还是在PC端中打开
Jan 06 Javascript
JavaScript 正则表达式中global模式的特性
Feb 25 Javascript
浅谈jquery中的each方法$.each、this.each、$.fn.each
Jun 23 Javascript
全面了解javascript三元运算符
Jun 27 Javascript
Angularjs中的页面访问权限怎么设置
Nov 11 Javascript
jQGrid Table操作列中点击【操作】按钮弹出按钮层的实现代码
Dec 05 Javascript
微信小程序返回多级页面的实现方法
Oct 27 Javascript
layui中使用jquery控制radio选中事件的示例代码
Aug 15 jQuery
详解使用mocha对webpack打包的项目进行"冒烟测试"的大致流程
Apr 27 Javascript
微信小程序自定义胶囊样式
Dec 27 Javascript
JS+CSS实现的竖向简洁折叠菜单效果代码
Oct 22 #Javascript
浅谈node.js中async异步编程
Oct 22 #Javascript
JS实现不使用图片仿Windows右键菜单效果代码
Oct 22 #Javascript
JS实现新浪博客左侧的Blog管理菜单效果代码
Oct 22 #Javascript
JS+CSS实现大气清新的滑动菜单效果代码
Oct 22 #Javascript
Webpack 实现 Node.js 代码热替换
Oct 22 #Javascript
JS+CSS实现仿msn风格选项卡效果代码
Oct 22 #Javascript
You might like
php jquery 实现新闻标签分类与无刷新分页
2009/12/18 PHP
PHP imagegrabscreen和imagegrabwindow(截取网站缩略图)的实例代码
2013/11/07 PHP
PHP内置加密函数详解
2016/11/20 PHP
PHP中单例模式的使用场景与使用方法讲解
2019/03/18 PHP
php面向对象程序设计中self与static的区别分析
2019/05/21 PHP
PHP基于timestamp和nonce实现的防止重放攻击方案分析
2019/07/26 PHP
laravel请求参数校验方法
2019/10/10 PHP
YII2框架中behavior行为的理解与使用方法示例
2020/03/13 PHP
为什么要在引入的css或者js文件后面加参数的详细讲解
2013/05/03 Javascript
JavaScript中的6种运算符总结
2014/10/16 Javascript
浅谈利用JavaScript进行的DDoS攻击原理与防御
2015/06/04 Javascript
js操作XML文件的实现方法兼容IE与FireFox
2016/06/25 Javascript
使用nodeJs来安装less及编译less文件为css文件的方法
2017/11/20 NodeJs
使用mock.js随机数据和使用express输出json接口的实现方法
2018/01/07 Javascript
vue 2.x 中axios 封装的get 和post方法
2018/02/28 Javascript
微信小程序实现简单评论功能
2018/11/28 Javascript
js 下拉菜单点击旁边收起实现(踩坑记)
2019/09/29 Javascript
vue组件添加事件@click.native操作
2020/10/30 Javascript
vue3.0中setup使用(两种用法)
2020/12/02 Vue.js
python读取图片并修改格式与大小的方法
2018/07/24 Python
python cs架构实现简单文件传输
2020/03/20 Python
Python分支语句与循环语句应用实例分析
2019/05/07 Python
python 对字典按照value进行排序的方法
2019/05/09 Python
django和flask哪个值得研究学习
2020/07/31 Python
详解Python的爬虫框架 Scrapy
2020/08/03 Python
沃达丰英国有限公司:Vodafone英国
2019/04/16 全球购物
全球异乡人的跨境社交电商平台:Kouhigh口嗨网
2020/07/24 全球购物
俄罗斯连接商品和买家的在线平台:goods.ru
2020/11/30 全球购物
办公室主任主任岗位责任制
2014/02/11 职场文书
暑期社会实践感言
2014/02/25 职场文书
服装发布会策划方案
2014/05/22 职场文书
优秀电子工程系毕业生求职信
2014/05/24 职场文书
护士先进个人总结
2015/02/13 职场文书
汽车质检员岗位职责
2015/04/08 职场文书
2015最新民情日记范文
2015/06/26 职场文书
Vue监视数据的原理详解
2022/02/24 Vue.js