JavaScript代码调试方法总结

JavaScript 调试

没有调试工具是很难去编写 JavaScript 程序的;你的代码可能包含语法错误,逻辑错误,如果没有调试工具,这些错误比较难于发现;通常,如果 JavaScript 出现错误,是不会有提示信息,这样你就无法找到代码错误的位置

JavaScript 调试工具

在程序代码中寻找错误叫做代码调试。调试很难,但幸运的是,很多浏览器都内置了调试工具;内置的调试工具可以开始或关闭,严重的错误信息会发送给用户

浏览器启用调试工具一般是按下 F12 键,然后通过console调试

console方法

Console 是用于显示 JS和 DOM 对象信息的单独窗口。并且向 JS 中注入1个 console 对象,使用该对象 可以输出信息到 Console 窗口中

有了调试工具,我们就可以设置断点 (代码停止执行的位置), 且可以在代码执行时检测变量

console对象的方法,都可以使用printf风格的占位符。不过,占位符的种类比较少,只支持字符(%s)、整数(%d或%i)、浮点数(%f)和对象(%o)四种

console.log("%d年%d月%d日",2011,3,26);
console.log("圆周率是%f",3.1415926);

%o占位符,可以用来查看一个对象内部情况

还有一种特殊的标示符%c,对输出的文字可以附加特殊的样式,当进行大型项目开发的时候,代码中可能有很多其他开发者添加的控制台语句

var dog = {};
dog.name = "大毛";
dog.color = "黄色";
console.log("%o", dog);

console.log(object[, object, ...])

使用频率最高的一条语句:向控制台输出一条消息。支持 C 语言 printf 式的格式化输出。当然,也可以不使用格式化输出来达到同样的目的:

var animal='frog', count=10;
console.log("The %s jumped over %d tall buildings", animal, count);
console.log("The", animal, "jumped over", count, "tall buildings");
console.debug(object[, object, ...])

向控制台输出一条信息,它包括一个指向该行代码位置的超链接。

console.info(object[, object, ...])

向控制台输出一条信息,该信息包含一个表示“信息”的图标,和指向该行代码位置的超链接。

console.debug(object[, object, ...])

在控制台输出一条消息,包含一个指向代码调用位置的超链接。假如是直接在控制台输入该命令,就不会出现超链接(和console.log()一样)

console.warn(object[, object, ...])

在控制台输出一条带有“警告”图标的消息和一个指向代码调用位置的超链接

console.error(object[, object, ...])

在控制台输出一条带有“错误”图标的消息和一个指向代码调用位置的超链接。error 实际上和 throw new Error() 产生的效果相同,使用该语句时会向浏览器抛出一个 js 异常。

console.assert(expression[, object, ...])

接收至少两个参数,第一个参数的值或返回值为false的时候,将会在控制台上输出后续参数的值


console.assert(1 == 1, object); // 无输出,返回 undefined
console.assert(1 == 2, object); // 输出 object

var isDebug = false;
console.assert(isDebug,'为false时输出的log信息...');

console.dir(object)

输出一个对象的全部属性(输出结果类似于 DOM 面板中的样式)。直接将该DOM结点以DOM树的结构进行输出,可以详细查对象的方法发展等等

var myObject = {
    a:'1',
    b:2,
    c:true,
    myFunc:function(){
        alert('hello world');
    }
};
console.dir(myObject);

console.dirxml(node)

用来显示网页的某个节点(node)所包含的html/xml代码,输出一个 HTML 或者 XML 元素的结构树,点击结构树上面的节点进入到 HTML 面板

<table id="mytable">
    <tr>
        <td>A</td>
        <td>A</td>
        <td>A</td>
    </tr>
    <tr>
        <td>bbb</td>
        <td>aaa</td>
        <td>ccc</td>
    </tr>
</table>
<script type="text/javascript">
    window.onload = function () {
        var mytable = document.getElementById(‘mytable‘);
        console.dirxml(mytable);
    }
</script>

console.trace()

console.trace()用来追踪函数的调用过程。在大型项目尤其是框架开发中,函数的调用轨迹可以十分复杂,console.trace()方法可以将函数的被调用过程清楚地输出到控制台上

function tracer(a) {
  console.trace();
  return a;
}

function foo(a) {
  return bar(a);
}

function bar(a) {
  return tracer(a);
}

var a = foo('tracer');

console.group(object[, object, ...])

这是个有趣的方法,它能够让控制台输出的语句产生不同的层级嵌套关系,每一个console.group()会增加一层嵌套,相反要减少一层嵌套可以使用console.groupEnd()方法

console.log('这是第一层');
console.group();
console.log('这是第二层');
console.log('依然第二层');
console.group();
console.log('第三层了');
console.groupEnd();
console.log('回到第二层');
console.groupEnd();
console.log('回到第一层');

和console.group()相似的方法是console.groupCollapsed()作用相同,不同点是嵌套的输出内容是折叠状态,在有大段内容输出的时候使用这个方法可以使输出版面不至于太长

console.groupEnd()

关闭最近一个由console.group打开的块

console.group('aaa');
console.warn('aaa.aaa');
console.groupEnd();
console.group('bbb');
console.info('bbb.bbb');
console.groupEnd();

console.groupCollapsed()

同 console.group(); 区别在于嵌套块默认是收起的。

console.time(name)

创建一个名字为name的计时器,当调用 console.timeEnd(name);并传递相同的 name 为参数时,计时停止,并输出执行两条语句之间代码所消耗的时间(毫秒)。

console.timeEnd(name)

停止同名的计时器并输出所耗时间(毫秒)

//第一种方法是用console.time来统计实例化1000000个对象所需时间
console.time('Array initialize');
var array = new Array(1000000);
for(var i = array.length-1;i>=0;i--){
    array[i] = new Object();
};
console.timeEnd('Array initialize');
//第二种方法使用传统的时间差相减来统计实例化1000000个对象所需的时间
var start = new Date().getTime();
var array1 = new Array(1000000);
for(var i = array.length-1;i>=0;i--){
    array[i] = new Object();
};
console.log(new Date().getTime()-start);

console.profile([title])

这是个挺高大上的东西,可用于性能分析。在 JS 开发中,我们常常要评估段代码或是某个函数的性能。在函数中手动打印时间固然可以,但显得不够灵活而且有误差。借助控制台以及console.profile()方法我们可以很方便地监控运行性能;与 profileEnd() 结合使用,用来做性能测试,与 console 面板上 profile 按钮的功能完全相同。

页面加载过程的性能优化是前端开发的一个重要部分,使用控制台的 profiles 面板可以监控所有 JS 的运行情况使用方法就像录像机一样,控制台会把运行过程录制下来

console.profileEnd()

关闭Javascript性能测试开关并输出报告

console.profile('Array initialize');
var array = new Array(1000000);
for(var i = array.length-1;i>=0;i--){
    array[i] = new Object();
};
console.profileEnd('Array initialize');

在Profiles面板里面查看就可以看到cpu相关使用信息

console.count([title])

当你想统计代码被执行的次数时,输出该行代码被执行的次数,参数 title 将在输出时作为输出结果的前缀使用。

function myFunction(){
    console.count('myFunction被执行的次数:');
}
myFunction();
myFunction();
myFunction();

console.table()

可将传入的对象,或数组以表格形式输出,相比传统树形输出,这种输出方案更适合内部元素排列整齐的对象或数组,不然可能会出现很多的 undefined

var obj = {
  foo: {
    name: 'foo',
    age: '33'
  },
  bar: {
    name: 'bar',
    age: '45'
  }
};
var arr = [
  ['foo', '33'],
  ['bar', '45']
];
console.table(obj);
console.table(arr);

console.timeLine和console.timeLineEnd配合一起记录一段时间轴

console.clear()

清空控制台

控制台的一些快捷键

方向键盘的上下键

大家一用就知晓。比如用上键就相当于使用上次在控制台的输入符号

$

命令返回最近一次表达式执行的结果,功能跟按向上的方向键再回车是一样的

在页面右击选择审查元素,然后在弹出来的DOM结点树上面随便点选,这些被点过的节点会被记录下来,而$0会返回最近一次点选的DOM结点,以此类推,$1返回的是上上次点选的DOM节点,最多保存了5个,如果不够5个,则返回undefined

Chrome 控制台中原生支持类jQuery的选择器

也就是说你可以用$加上熟悉的css选择器来选择DOM节点

copy

通过此命令可以将在控制台获取到的内容复制到剪贴板

keys和values

前者返回传入对象所有属性名组成的数据,后者返回所有属性值组成的数组

var myObj = {name:'angela',sex:'female',hobby:'programs'};
keys(myObj);
values(myObj);

monitor & unmonitor

monitor & unmonitor

monitor(function),它接收一个函数名作为参数,比如function a,每次a被执行了,都会在控制台输出一条信息,里面包含了函数的名称a及执行时所传入的参数。而unmonitor(function)便是用来停止这一监听

function sayHello(name){
    alert('hello,'+name);
}
monitor(sayHello);
sayHello('angular');
unmonitor(sayHello);
sayHello('haha');

也就是说在monitor和unmonitor中间的代码,执行的时候会在控制台输出一条信息,里面包含了函数的名称a及执行时所传入的参数。当解除监视(也就是执行unmonitor时)就不再在控制台输出信息了

命令行

控制台的输出面板右边,是控制台的输入面板(Chrome 调试工具对应为下方),在这里除了可以运行常规的 javascript 代码,还内置了相当数量的命令行可以辅助我们的调试工作,下面是一些常用命令行的简单介绍。

$(id)

返回一个给定 id 的元素。

$$(selector)

返回给定的 css 选择器匹配到的一组元素。

$x(xpath)

返回给定的 XPath 表达式匹配到的一组元素。

$0

在 HTML 面板中选中的元素。

$1

上一次在 HTML 面板中选中的元素。

$n(index)

访问最近 5 个被选中过的元素,index 的范围: 0 – 4。

dir(object)

同 console.dir(object)。

dirxml(node)

同 console.dirxml(node)。

clear()

同 console.clear()。

inspect(object[, tabName])()

在合适的(或一个指定的) tab 中检视一个对象。

keys(object)

返回一个对象的所有属性的键。

values(object)

返回一个对象的所有属性的值。

debug(fn)

在函数第一行添加一个断点,使用 undebug(fn) 移除断点。

monitor(fn)

开启一个函数的调用日志,使用 unmonitor(fn) 关闭该功能。非常有用的一个命令,但是它似乎并没有很好地工作。

monitorEvents(object[, types])

开启一个元素的某个事件(或所有事件)被触发时的日志记录。用例如下:

monitorEvents($0,['click'])

上面的命令行被执行后,将开启当前在 HTML 面板中被选中元素的 click 事件监控,一旦这个元素的 click 事件被触发,事件对象将会在控制台输出。如果不指定第二个参数,将对所有事件进行记录。

profile([title])

同 console.profile([title])

设置断点

在这里,我们可以使用快捷键进行操作,常用的快捷键如下:

F9:添加/移除 断点

F10:逐过程,即跳过该语句中的方法、表达式等

F11:逐语句调试,即单步调试,会跳入方法、表达式,进行逐语句的跟踪调试

断点调试是啥

断点调试其实并不是多么复杂的一件事,简单的理解无外呼就是打开浏览器,打开sources找到js文件,在行号上点一下罢了

断点怎么打才合适

假设我们现在正在实现一个加载更多的功能出现了问题,点击以后数据没有加载出来,这时候我们第一时间想到的应该是什么?

我最先想到的是,我点击到底有没有成功?点击事件里的方法有没有运行?好,要想知道这个问题的答案,我们当然是在代码中的点击事件处添加一个断点,然后做什么呢?然后我们当然是回去点击加载更多按钮来确定是否有问题啦

debugger 关键字

这种方法很简单,我们只需要在进行调试的地方加入debugger关键字,然后当浏览器运行到这个关键字的时候,就会提示是否打开调试,我们选择是就可以了。这种调试可以选择调试工具,是新打开vs还是在现有的VS中调试,都可以选择

debugger 关键字用于停止执行 JavaScript,并调用调试函数;这个关键字与在调试工具中设置断点的效果是一样的;如果没有调试可用,debugger 语句将无法工作;下面例子开启 debugger ,代码在第三行前停止执行

var x = 15 * 5;
debugger;
document.getElementbyId("demo").innerHTML = x;

主要浏览器的调试工具

通常,浏览器启用调试工具一般是按下 F12 键,并在调试菜单中选择 "Console"
各浏览器的步骤如下:

Chrome 浏览器

打开浏览器 - 在菜单中选择工具 - 在工具中选择开发者工具 - 最后,选择 Console

Firefox 浏览器

打开浏览器 - 访问页面:http://www.getfirebug.com - 按照说明安装 Firebug

Internet Explorer 浏览器。

打开浏览器 - 在菜单中选择工具 - 在工具中选择开发者工具 - 最后,选择 Console

Opera

打开浏览器 - Opera 的内置调试工具为 Dragonfly,详细说明可访问页面:http://www.opera.com/dragonfly/

Safari

打开浏览器 - 访问页面:http://extentions.apple.com - 按说明操作:install Firebug Lite

上一篇:Java 你的多继承纳?


下一篇:【JavaScript框架封装】实现一个类似于JQuery的事件框架的封装