写在前面: 本文包括浏览器调试, 不包括 web 移动端调试. 本文调试均在 Chrome 浏览器进行.
alert
这个不用多说了, 不言自明.
console
基本输出
想必大家都在用 console.log 在控制台输出点东西, 其实 console 还有其它的方法:
- console.log( "打印字符串" ); // 在控制台打印自定义字符串
- console.error( "我是个错误" ); // 在控制台打印自定义错误信息
- console.info( "我是个信息" ); // 在控制台打印自定义信息
- console.warn( "我是个警告" ); // 在控制台打印自定义警告信息
- console.debug( "我是个调试" ); // 在控制台打印自定义调试信息
- cosole.clear(); // 清空控制台(这个下方截图中没有)
注意上面输出的 error 和 throw 出的 error 不一样, 前者只是输出错误信息, 无法捕获, 不会冒泡, 更不会中止程序运行.
格式化输出
除此以外, console 还支持自定义样式和类似 c 语言的 printf 形式:
- console.log("%s 年" , 2016 ); //%s 表示字符串
- console.log( "%d 年 %d 月" , 2016 , 11 ); //%d 表示整数
- console.log( "%f" , 3.1415926 ); //%f 小数
- console.log( "%o" ,console);//%o 表示对象
- console.log( "%c 自定义样式" , "font-size:30px;color:#00f" );
- console.log( "%c 我是 %c 自定义样式" , "font-size:20px;color:green" , "font-size:10px;color:red" );
DOM 输出
下面几个比较简单的, 就不举例子了, 简单说一下:
- var ul = document.getElementsByTagName( "ul" );
- console.dirxml(ul);
- // 树形输出 table 节点, 即和它的 innerhtml, 由于 document.getElementsByTagName 是动态的, 所以这个得到的结果肯定是动态的
对象输出
- var o = {
- name: "Lily" , age: 18
- };
- console.dir(obj);
- // 显示对象自有属性和方法
对于多个对象的集合, 你可以这样, 输出更清晰:
- var stu = [{
- name:"Bob",age:13,hobby:"playing"
- },{
- name:"Lucy",age:14,hobby:"reading"
- },{
- name:"Jane",age:11,hobby:"shopping"
- }];
- console.log(stu);
- console.table(stu);
成组输出
- // 建立一个参数组
- console.group("start"); // 引号里是组名, 自己起
- console.log("sub1");
- console.log("sub1");
- console.log("sub1");
- console.groupEnd("end");
函数计数和跟踪
- function fib(n){ // 输出前 n 个斐波那契数列值
- if(n == 0) return;
- console.count("调用次数");// 放在函数里, 每当这句代码运行输出所在函数执行次数
- console.trace();// 显示函数调用轨迹(访问调用栈)
- var a = arguments[1] || 1;
- var b = arguments[2] || 1;
- console.log("fib=" + a);
- [a, b] = [b, a + b];
- fib(--n, a, b);
- }
- fib(6);
注: Chrome 开发者工具中的 Sources 标签页也在 Watch 表达式下面显示调用栈.
计时
- console.time() // 计时开始
- fib(100); // 用上述函数计算 100 个斐波那契数
- console.timeEnd() // 计时结束并输出时长
断言语句, 这个 c++ 调试里面也经常用到. JS 中, 当第一个表达式或参数为 true 时候什么也不发生, 为 false 时终止程序并报错.
- console.assert(true, "我错了");
- console.assert(false, "我真的错了");
性能分析
- function F(){
- var i = 0;
- function f(){
- while(i++ == 1000);
- }
- function g(){
- while(i++ == 100000);
- }
- f();
- g();
- }
- console.profile();
- F();
- console.profileEnd();
注: Chrome 开发者工具中的 Audits 标签页也可以实现性能分析.
debugger
这个重量级的是博主最常用的, 可能是 c++ 出身, 对于单步调试由衷的热爱. 单步调试就是点一下, 执行一句程序, 并且可以查看当前作用域可见的所有变量和值. 而 debugger 就是告诉程序在那里停下来进行单步调试, 俗称断点.
右边按钮如下:
Pause/Resume script execution: 暂停 / 恢复脚本执行(程序执行到下一断点停止).
Step over next function call: 执行到下一步的函数调用(跳到下一行).
Step into next function call: 进入当前函数.
Step out of current function: 跳出当前执行函数.
Deactive/Active all breakpoints: 关闭 / 开启所有断点(不会取消).
Pause on exceptions: 异常情况自动断点设置.
其实右侧还有很多强大的功能:
Watch:Watch 表达式
Call Stack: 栈中变量的调用, 这里是递归调用, 肯定是在内存栈部分调用.
Scope: 当前作用域变量观察.
BreakPoints: 当前断点变量观察.
XHR BreakPoints: 面向 Ajax, 专为异步而生的断点调试功能.
DOM BreakPoints: 主要包括下列 DOM 断点, 注册方式见下图:
当节点属性发生变化时断点(Break on attributes modifications)
当节点内部子节点变化时断点(Break on subtree modifications)
当节点被移除时断点(Break on node removal)
Global Listeners: 全局事件监听
Event Listener Breakpoints: 事件监听器断点, 列出了所有页面及脚本事件, 包括: 鼠标, 键盘, 动画, 定时器, XHR 等等.
Chrome 中的调试技巧
1,DOM 元素的控制台书签: Chrome 开发者工具和 Firebug 都提供了书签功能, 用于显示你在元素标签页 (Chrome) 或 HTML 标签页 (Firebug) 中最后点击的 DOM 元素. 如果你依次选择了 A 元素, B 元素和 C 元素, 那么 \$0 表示 C 元素, \$1 表示 B 元素, \$2 表示 A 元素(这个和正则表达式的 \$ 符号类似, 不过顺序不同).
2, 如果你想调试 f 函数, 用 debug(f)语句可以增加这种断点.
3,Sources 标签页左侧面板上有一个代码片段 (Snippet) 子标签页, 可用于保存代码片段, 帮你调试代码.
4, 可以用 Chrome 开发者工具 Sources 标签页中的格式化按钮 (Pretty Print Button) 格式化压缩后的代码.
5, 在 Network 面板, 选择一个资源文件, 右键 Copy Response 可快速复制响应内容.
6, 利用媒体查询, 这个主要是在 Device Mode 调节不同的分辨率显示.
7, 选择 Elements, 按 Esc> Emulation> Sensors 进行传感器模拟.
8, 点击渐入效果样式图标 (紫色图标), 可以预览动画效果, 并可对相应的贝塞尔曲线(cubic-bezier) 进行调节动画效果.
9, 在 Source 中按住 Alt 键并拖动鼠标进行多列内容选择.
10,Elements 面板右键执行 DOM 元素节点, 选择 Force Element State 或者点击右侧 Toggle Element State 图标可以出发伪类.
11,Network 面板中选择一张图片, 在右侧图片上鼠标右键选择 copy it as a Data URI, 就可以获取图片的 Data URL (base64 编码).
12, 通过按住 Ctrl 键可以添加多个编辑光标, 同时对多处进行编辑. 按下 Ctrl + U 可以撤销编辑.
13,Elements 面板右侧的 Style 编辑器中, 点击颜色十六进制编码前的小色块, 会弹出一个调色板.
14, 按下 Alt 键并且鼠标双击选择 DOM 元素前面的箭头, 就会展开该 DOM 元素下的所有字节点元素.
15, 快捷键:
快速定位到行: 快捷键 Ctrl+O(Mac: CMD+O), 输入: 行号: 列号 来进行定位
元素搜索: 快捷键 Ctrl+F(Mac: CMD+F), 试试在搜索栏输入 ID 选择符或者类选择符就可以定位到元素啦
调试过程注意事项
1, 避免记录引用类型
当记录对象或数组时, 永远记得你在记录什么. 记录原始类型时, 使用带断点的 watch 表达式. 如果是异步代码, 避免记录引用类型.
- var arr = [{
- num: 0
- }];
- setInterval(function(){
- console.log(arr);
- arr[0].num += 1;
- }, 1000);
这里, 第一个属性中对象引用的值是不可靠的. 当你第一次在开发者工具中显示这个属性时, num 的值就已经确定了. 之后无论你对同一个引用重新打开多少次都不会变化.
2, 尽可能使用 source map. 有时生产代码不能使用 source map, 但不管怎样, 你都不应该直接对生产代码进行调试.
来源: http://developer.51cto.com/art/201902/592076.htm