小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
前言
吃饱饭才有力气写代码~
今天学习一下常用的几种前端代码调试技术,在JavaScript调试器出现之前,最为常用的调试技术就是在相关代码中插入alert(),这种方法在调试完还得清理,如果有漏洞的警告框出现在产品环境中还会给用户带来不便,所以现在不推荐把警告框用于调试,以下这些方法相比较会更好!
一.把消息记录到控制台
所有主流浏览器都有JavaScript控制台,该控制台可以用于查询JavaScript错误,此外这些浏览器都支持通过console对象直接把JavaScript消息写入控制台,这个对象包含如下方法:
error():在控制台记录错误信息
info():在控制台中记录信息性内容
log():在控制台记录常规消息
warn():在控制台中记录警告消息
记录消息时使用的方法不同,消息显示的样式也不想同,错误消息包含一个红叉图标,而警告消息包含一个黄色叹号图标。把消息输出到JavaScript控制台可以辅助调试代码,但是在产品环境下应该删除所有相关代码,这可以在部署时使用代码自动完成清理,也可以手动删除。
二.补充控制台方法
记住使用哪个日志方法(原生的console.log()和自定义的log()方法)对于开发者来说是一种负担,因为console是一个全局对象,所以可以为这个对象添加方法,也可以用自定义的函数重写已有的方法,这样无论在哪里用到的日志打印方法都会按照自定义的方法运行。比如下面这种重新定义console.log函数:
//把所有参数拼接为一个字符串,然后打印结果
console.log = function(){
const args = Array.prototype.slice.call(arhuments);//'arguments'并没有join方法,这里先把它转换为数组
console.log(args.join(','));
}
这样其它代码调用的会是这个函数,而不是通用的日志方法,这样的修改在页面刷新后会失效,所以这只是一个调试或者拦截日志的一个有用而轻量的策略。
三.在页面打印消息
另一种常用的打印调试消息的方式就是把消息写在页面中指定的区域,这个区域可以是所有页面中都包含的元素,但仅用于调试;也可以在需要时创建临时的元素,例如可以像下面这样定义log()函数:
function log(message){
const console = document.getElementById("debuginfo");
if(console == null){
console = document.createElement("div");
console.id = "debuginfo";
console.style.background = "#dedede";
console.style.border = "1px solid silver";
console.style.padding = "5px";
console.style.width = "400px";
console.style.position = "absolute";
console.style.right = "0px";
console.style.top = "0px";
document.body.appendChild(console);
}
console.innerHtml += '<p>${message}</p>';
}
在这个log()函数中,代码先检测是否已经创建了调试用的元素,如果没有就创建一个新的div并添加一些样式,以便其与其它部分区分开,之后再用innerHtml属性把消息写到这个div里,结果就是在页面的一个小区域内显示日志信息。这个和在控制台输出消息一样,在页面中输入消息的代码也需要从生产环境中删除。
四.抛出错误
抛出错误也是一种调试代码很好的方法,好的错误消息包含关于错误原因的确切信息,因此可以减少额外调试的工作量,比如下面这个例子:
function chufa(num1,num2){
if(typeof num1 != "number" || typeof num2 != "number"){
throw new Error("chufa():Both arguments must be numbers.");
}
return num1/num2;
}
这里任何一个参数不是数值都会抛出错误,错误消息中包含函数名和错误的具体原因,当浏览器报这个错误时,就可以根据它包含的信息定位到问题。在很多应用程序中,自定义错误通常会用assert()函数来抛出错误。这个函数接收一个应该为true的条件,并在条件为false时抛出错误,上面的例子可以改为:
//function assert(condition,message){
// if(!condition){
// throw new Error(message);
// }
//}
function chufa(num1,num2){
assert(typeof num1 == "number" && typeof num2 == "number","chufa():Both arguments must be numbers.");
return num1/num2;
}
相较于之前的例子,使用assert()函数可以减少抛出自定义错误所需要的代码量,并且让代码很容易理解。