《JAVASCRIPT高级程序设计》错误处理与调试
一、错误处理
错误处理在程序设计中的重要性是毋庸置疑的,任何有影响力的web应用程序都需要一套完善的错误处理机制。良好的错误机制可以让用户得到提醒,知道发生了什么事。
1、try-catch语句
try-catch语句是javascript处理异常的一种标准方式,它的结构如下:
try{
// 把所有可能出现错误的代码放在try语句中
}catch(err){
// 把用于处理错误的块放在catch语句中
// catch块会接受到一个保存错误信息的对象
// 该对象的message属性是唯一一个能够保证所有浏览器都支持的属性
alert(err.message);
}finally{
// finally子句无论如何都会执行
}
2、错误类型
javascript有7种错误类型,其中,Error是基类型,其他错误都继承自该类型。
- Error
- EvalError
- RangeError
- ReferenceError
- SyntaxError
- TypeError
- URIError
// eval()会计算字符串中的值,并执行其中的js代码
// 正确使用
eval("2+3");
// ECMA-262规定,如果没有把eval()当做函数调用,就会发生错误;但实践中,浏览器不一定会在应该抛出错误的时候就抛出EvalError
new eval();
eval = fool
// RangeError类型的错误会在数值超过相应范围时触发 var item1 = new Array(-20); var item2 = new Array(Number.MAX_VALUE);
// 在找不到对象的情况下,会发生ReferenceError var obj=x;
// 把语法错误的字符串给eval()时,会导致SyntaxError
eval("1++2");
// 在变量中保存意外的类型,或访问不存在的方法时,都会抛出TypeError错误
var o = new 10;
alert("name" in true);
3、抛出错误
使用throw语句,可以抛出上述的错误,也可以抛出自定义的错误;在遇到throw操作符时,代码会立刻停止执行。
// 抛出常规错误
throw new SyntaxError("I don't like your syntax");
throw new TypeError("What type of variable do you take me for?");
throw new RangeError("Sorry, you just don't have the range");
throw new EvalError("That't doesn't evaluate.");
throw new URIError("Uri, is that you?");
throw new ReferenceError("You didn't cite your references properly.");
// 抛出自定义错误
function CustomError(message){
this.name = "CustomError";
this.message = message;
}
CustomError.prototype = new Error();
throw new CustomError("My message");
4、常见的错误类型
一般来说,需要关注三种类型的错误:
- 类型转换错误
- 数据类型错误
- 通信错误
a)类型转换错误
为避免类型转换错误,建议使用全等操作符:
alert(5=="5");//true alert(5==="5");//false
流控制语句也很容易出错。像if之类的语句,在确定下一步操作之前,会自动把任何值转化成布尔值:
function concat(str1, str2, str3){
var result = str1 + str2;
if(str3){ //当str3是大于0的数字,不是string类型时,也会执行
resutl += str3;
}
return result;
}
// 正确的写法
function concat(str1, str2, str3){
var result = str1 + str2;
if(typeof str3=="string"){
resutl += str3;
}
return result;
}
b)数据类型错误
在将变量传递个函数时,对变量进行类型进行检测,可以避免类型错误:
// 不安全的函数,任何非字符串都会导致错误
function getQueryString(url) {
var pos = url.indexOf("?");
if (pos > -1) {
return url.substring(pos + 1);
}
return "";
}
// 安全的函数
function getQueryString(url) {
if (typeof url == "string") {//通过检查类型确保安全
var pos = url.indexOf("?");
if (pos > -1) {
return url.substring(pos + 1);
}
return "";
}
}
在确切知道应该传入什么类型的情况下,应该使用instanceof Array来检测类型:
/ 不安全的函数,任何非数组类型都会导致错误
function reverseSort(values){
if(values){
values.sort();
valuse.reverse();
}
}
// 不安全的函数,任何非数组类型都会导致错误
function reverseSort(values){
if(values != null){
values.sort();
valuse.reverse();
}
}
// 不安全的函数,不能只针对某个特性进行检测
function reverseSort(values){
if(typeof values.sort == "function"){
values.sort();
valuse.reverse();
}
}
// 安全,非数组将被忽略
function reverseSort(values){
if(values instanceof Array){
values.sort();
valuse.reverse();
}
}
c)数据通信错误
常见的数据通信错误是把数据发给服务器之前,没有使用encodeURIComponent()对数据进行编码,可以定义一个处理查询字符串的函数:
function addQueryStringArg(url, name ,value){
if(url.indexOf("?") == -1){
url += "?";
}else{
url += "&";
}
url += encodeURIComponent(name) + "=" +encodeURIComponent(value);
return url;
}
var url = "http://www.baidu.com";
var newUrl = addQueryStringArg(url, "redir", "http://wwww.someotherdomain.com?a=b&b=c");
alert(newUrl);
5、非致命错误与致命错误:
非致命错误:不影响用户的主要任务/只影响页面的一部分/可以恢复/重复相同操作可以消除错误
这类错误没有必要对用户给出提示---可以直接把页面中受影响的区域替换掉。
致命错误:应用程序根本无法运行/错误明显影响到了用户的主要操作/会导致其他连带错误
这类错误应该立即给用户发送消息,告诉他们无法继续进行手头上的事情了。
二、调试技术
1、可以使用console对象向javascript控制台写入消息来调试
function sum(num1, num2){
console.log("Enter sum(), arguements are " + num1 + ", " +num2 );
console.log("Before calculation");
var result = num1 + num2;
console.log("After calculaation");
console.log("Exiting sum()");
return result;
}
2、将消息记录在当前页面
在页面开辟一小块信息,用于显示错误信息
<html>
<head>
<meta charset = "utf-8">
</head>
<body>
<script>
function log(message){
var 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("test……");
</script>
</body>
</html>
3、直接抛出错误
如果错误消息很具体,基本可以把它当做错误来源的依据,那么可以直接抛出错误:
function divide(num1, num2){
if(typeof num1 != "number" || typeof num2 != "number"){
throw new Error("devide (): both arguments must be number.");
}
return num1 / num2;
}
也可以自定义一个assert语句,抛出错误:
//assert接受两个参数,一个是求值结果应该为true的条件,一个是条件为false时需要抛出的错误
function assert(condition , message){
if(!condition){
throw new Error(message);
}
}
function divide(num1, num2){
assert(typeof num1 == "number" && typeof num2 == "number", "devide (): both arguments must be number.");
return num1 / num2;
}
三、常见的IE的错误
IE是最难调试JAVASCRIPT错误的浏览器,以下介绍一些错误:
1、操作中止
对于IE8之前的版本,在修改尚未加载完的页面时,会发生操作中止错误:
<!doctype html>
<html>
<head>
<title>Operation Aborted Example</title>
</head>
<body>
<p> The following code should cause an Operation Aborted error in IE Versions prior to 8.</p>
<div>
<script type="text/javascript">
document.body.appendChild(document.createElement("div"));
</script>
</div>
</body>
</html>
解决办法可以是不适用appendChild(),而使用insertBefore():
<!doctype html>
<html>
<head>
<title>Operation Aborted Example</title>
</head>
<body>
<p> The following code should cause an Operation Aborted error in IE Versions prior to 8.</p>
<div>
<script type="text/javascript">
document.body.insertBefore(document.createElement("div"),document.body.firstChild);
</script>
</div>
</body>
</html>
也可以把script元素移除来,直接作为<body>的子元素:
<!doctype html>
<html>
<head>
<title>Operation Aborted Example</title>
</head>
<body>
<p> The following code should cause an Operation Aborted error in IE Versions prior to 8.</p>
<div>
</div>
<script type="text/javascript">
document.body.appendChild(document.createElement("div"));
</script>
</body>
</html>
2、无效字符
无效字符是Javascript中没有定义的字符,例如直接从word中赋值文本到编辑器里,然后又在IE中运行,则可能会遇到无效字符的错误。
3、未找到成员
以下函数在单击事件后,window.event对象会被保存;当单击事件执行完毕后,event对象就会被销毁,因而setTimeout中使用的对象就不存在了;因此会出现未找到成员的错误:
document.onclick = function(){
var event = window.event;
setTimeout(function(){
event.returnValue = false; //未找到成员函数
},1000);
}
4、未知运行时错误
当使用innerHTML或者outerHTML以下列方式操作时会发生错误:1)把块级元素插入到行内元素;2)访问表格的任意部分的任意属性
5、语法错误
6、系统无法找到指定资源
当URL的长度超过IE对URL的最长不能超过2083个字符的限制时,就会发生这个错误:
function createLongUrl(url){
var s = "?";
for(var i = 0, len = 2500; i < len; i++ ){
s += "a";
}
return url + s;
}
var x = new XMLHttpRequest();
x.open("get", createLongUrl("http://www.baidu.com/"), true);
x.send(null);
《JAVASCRIPT高级程序设计》错误处理与调试的更多相关文章
- 17. javacript高级程序设计-错误处理与调试
1. 错误处理与调试 l 在可能发生错误的地方使用try-catch方法,可以对错误进行及时的相应 l 使用window.onerror事件处理程序,这种方式可以接受try-catch不能处理的所有错 ...
- 《javascript高级程序设计》 touch事件的一个小错误
最近一段时候都在拜读尼古拉斯大神的<javascript高级程序设计>,真的是一本好书,通俗易懂,条理比<javascript权威指南>好理解一些,当然<javascri ...
- 读书笔记(04) - 错误监控 - JavaScript高级程序设计
错误类型 即时运行错误 (代码错误) 资源加载错误 常见的错误 1. 类型转换错误 建议使用全等===操作符 2.数据类型错误 建议加强类型判断 // 数组倒序 function reverseSor ...
- 《JavaScript高级程序设计(第3版)》阅读总结记录第一章之JavaScript简介
前言: 为什么会想到把<JavaScript 高级程序设计(第 3 版)>总结记录呢,之前写过一篇博客,研究的轮播效果,后来又去看了<JavaScript 高级程序设计(第3版)&g ...
- 读书笔记(02) - 可维护性 - JavaScript高级程序设计
编写可维护性代码 可维护的代码遵循原则: 可理解性 (方便他人理解) 直观性 (一眼明了) 可适应性 (数据变化无需重写方法) 可扩展性 (应对未来需求扩展,要求较高) 可调试性 (错误处理方便定位) ...
- 《Javascript高级程序设计》阅读记录(四):第五章 下
这个系列,我会把阅读<Javascript高级程序设计>之后,感觉讲的比较深入,而且实际使用价值较大的内容记录下来,并且注释上我的一些想法.做这个一方面是提升了我的阅读效果以及方便我以后阅 ...
- JavaScript高级程序设计第三版.CHM【带实例】
从驱动全球商业.贸易及管理领域不计其数的复杂应用程序的角度来看,说 JavaScript 已经成为当今世界上最流行的编程语言一点儿都不为过. JavaScript 是一种非常松散的面向对象语言,也是 ...
- javascript高级程序设计学习笔记
javascript高级程序设计,当枕头书已经好久了~zz 现在觉得自己在js的开发上遇到了一些瓶颈,归根究底还是基础太薄弱,所以重新刷一遍js高程希望有更新的认识. 一.javascript简介 ...
- JavaScript高级程序设计(第4版)pdf 电子书
JavaScript高级程序设计(第4版)pdf 电子书 免责声明:JavaScript高级程序设计(第4版)pdf 电子书下载 高清收集于网络,请勿商用,仅供个人学习使用,请尊重版权,购买正版书籍. ...
- JavaScript高级程序设计(第4版)知识点总结
介绍 JavaScript高级程序设计 第四版,在第三版的基础上添加了ES6相关的内容.如let.const关键字,Fetch API.工作者线程.模块.Promise 等.适合具有一定编程经验的 W ...
随机推荐
- logback配置
好吧,项目中一直使用的是logback做日志记录. 开始跑Demo的时候,一直会报Failed to load class org.slf4j.impl.StaticLogger的错误.后来googl ...
- 程序ajax请求公共组件app-jquery-http.js中url参数部分的项目应用
结合微信登录以及微信支付的案例:= =||| (案例比较奇葩复杂) 简述项目流程: 1.获取用于公众号支付的openid(公众平台):在微信内置浏览器中打开网页链接,刚进入页面就通过微信公众平台获取该 ...
- Handler和Message以及Looper之间的三角关系
说到Handler想必大家都经常用到,在非UI线程更新UI那可是利器,用起来也非常容易上手 从使用上来说,我们只需要关注sendMessage和handleMessage即可 所以我们先从Handle ...
- jquery 改变变量出现值不同步
出现问题的代码 var unc = 0; $.get( 'index.php', 'data=1', function(res) { unc=1; } ); alert(nuc); 这样的话,不管aj ...
- BZOJ 2705 [SDOI2012]Longge的问题 ——Dirichlet积
[题目分析] 狄利克雷卷积. 然后直接求出欧拉函数,计算和即可. [代码] #include <cstdio> #include <cstring> #include < ...
- HTML 表单元素之 input 元素
介绍HTML 5: 表单元素之 input 元素 表单元素之 input 元素 - text, password, url, telephone, email, search, file, radio ...
- 我的java信息
Java的运行环境版本: 1.7.0_07Java的运行环境供应商: Oracle CorporationJava供应商的URL: http://java.oracle.com/Java的安装路径: ...
- 一个a::before的写法
#key_table table tr td a::before{//这是个a前面的蓝色小圆点 background: #48A7D9; content: "";//这 ...
- Intellij idea 15配置tomcat,maven
刚导了个项目进去,想把项目运行起开,怎么也找不到tomcat... ctrl + alt +s,打开设置窗,搜索 Application Server Tomcat: 点中间绿色的“+”号,添加选择t ...
- wukong搜索引擎源码解读
转自:https://ayende.com/blog/171745/code-reading-wukong-full-text-search-engine I like reading code, a ...