} 错误处理的重要性
以前,javascript总是因为会出现奇怪的令人困惑的错误消息而知名,调试这种信息确实是一种痛苦的经历。
因此,第四版的浏览器(IE4.0和Netscape4.0)包含了一些基本的错误处理功能。不久之后,ECMA和ECMASCript第三版中提出新的解决方案。
最新的ECMAScript添加了异常处理机制,采用了从Java中移植过来的模型,第三版用ECMAScript第二版中的一些保留字实现了try…catch..finally结构以及throw操作符
1.1、早期浏览器的错误处理
早期的浏览器(如IE3.0)没有错误处理。函数通过返回一个无效值(一般是null、false或-1,根据不同的函数不同)来表示发生了错误,考虑以下代码:
var index = findColor(colorarray,”red”);
If (index==-1)
alert(“该项不存在”);
else
alert(“该项的位置是:”+index);
以上的问题在于函数findcolor的返回值-1无从判断是没有找到还是出错了。
错误和错误处理将帮助我们解决这个问题
在javascript引入错误处理后,web开发人员就可以更好的对代码进行控制了。好的错误处理技术可以让脚本的开发、测试和部署更流畅。Js尤为如此,因为它缺乏标准的开发环境来指导开发人员。
} 错误和异常
错误的类型无外两种:语法错误和运行时错误
1、语法错误
传统编程语言编译时解析错误,在javascript中发生在解释时。这些错误是由代码中的意外字符直接造成的。然后就不能完全编译/解释了,如:
window.alert(“test”
不过,在javascript中,只有在同一线程中的代码会受到错误代码的影响。在其他线程中的代码和其他外部引用的文件中的代码,如果不依赖于包含错误的代码,则可以继续执行
如:
<head>
<script type=“text/javascript”>
function handlerLoad() {
windows.open(“about:blank”);
}
function handleClick(){
alert(“click”);
}
</script>
</head>
<body onload =“handlerLoad()”>
<input type=“button” value=“test” onclick=“handlerClick()”/>
</body>
这段JS代码,页面载入时会报JS错误,但不会影响handleClick的执行
} 处理错误
Javascript提供了两种特殊的错误处理方式
BOM包含一个onerror事件处理函数,这个window对象与图像对象上都有
同时ECMAScript定义了另一个从java中借鉴过来的try…catch结构来处理异常
u onerror事件处理函数
<SCRIPT LANGUAGE="JavaScript">
<!--
function handleError(){
alert("出错了");
return true;}
window.onerror = handleError; //屏蔽所有的错误提示,很危险
//-->
</SCRIPT>
</HEAD>
<BODY onload="handleLoad()">
</BODY>
</HTML>
这样,网页出错,便会弹出”出错了“消息框”,但不幸的是网页仍会弹出错误提示框
如果想去掉这个提示框,改造如下:
} function handleError()
} {
} alert("出错了");
} return true;
} }
u 取出错误信息
onerror事件处理函数提供了三种信息来确定错误确切的性质
ü 错误信息—对于给定错误,浏览器会显示同样的信息
ü URL – 在哪个文件中发生了错误
ü 行号 – 给定URL中发生的错误的行号
如:<SCRIPT LANGUAGE="JavaScript">
<!--
function handleError(sMessage,sURL,sLine) {
alert(“出错了.\n”+“消息:"+sMessage+"\nURL:"+sURL+
"\n出错行号:"+sLine);
return true; }
window.onerror = handleError;
//-->
</SCRIPT>
//定制我们的错误提示
图像载入错误
<img src=“blue.gif” onerror=“alert(‘载入图像出错’)”/>
和window.onerror不同,img的onerror事件处理函数无任何额外消息的参数.
图片没正常加载就会触发onerror事件
使用onerror事件处理函数的主要问题是,它是BOM的一部分,所以,没有任何的标准能控制它们的行为。因此任何的浏览器使用这个事件处理函数处理错误的方式也明显不同。
如:IE中发生error事件时,正常的代码会继续执行;所有的变量和数据会保留下来,并可通过onerror事件处理函数访问。然而在mozilla中,正常的代码执行都会结束,同时所有错误处理之前的变量和数据都会被销毁。
还有其浏览器根本不支持window对象上的onerror事件处理函数,但它们都支持图像上的onerror事件
try…catch语句
ECMAScript第三版支持try…catch…finally语法
基本语法:
try{
//code
}catch([exception]){
//code
}[finally{
//code
}]
如:<SCRIPT LANGUAGE="JavaScript">
<!--
try{
alert("ok");
}catch(exception){
alert("an error processed");
}finally{
alert("finally");
}
alert("ok");
//-->
</SCRIPT>
注意:与java语言不同的是:不支持多重catch语句,但支持嵌套catch语句
如:try{ var a = document.getElementById("txtUser");
alert(a.value);
}catch(ex) {
alert(“Error”);
}
再如: 弹出详细错误信息try{ var a = document.getElementById("txtUser");
alert(a.value);
}catch(ex) {
alert(ex.message); //error
}
try{ var a = document.getElementById("txtUser");
alert(a.value);
}catch(ex)
{try{
alert(oException.message);}
catch (ex){
alert(ex.message); } }
} Error对象
类似于java的错误基类Exception,javascript有个基类Error,Error对象有以下特征:
p name –表示错误类型的字符串
p message – 实际的错误信息
Error对象的名称对应于它的类,可以是以下值之一
1、EvalError: 错误发生在eval()函数中
2、RangeError:数字的值超过javascript可表示的范围
3、ReferenceError: 使用了非法的引用
4、SyntaxError: 在eval()函数调用中发生了语法错误。
5、TypeError:变量的类型不是预期所需的
6、URIError: 在encodeURI()或者decodeURI()函数中发生的错误
说明:Mozzilla和IE均扩展了Error对象,如IE中提供了一个number特性来表示错误代号,也可用description代替message
错误类型判断 二种方法:
方法1:通过name属性判断
方法2: 通过instanceof操作符
如:try{ var scriptStr =" var a=0;var b=1;var c=a++b;alert(c)";
eval(scriptStr);
}catch(ex)
{ if (ex instanceof SyntaxError)
{ alert("语法出错了"); } }
抛出异常
ECMASCript还引入throw语句,用于有目的的抛出异常
语法如下:throw error_object
error_object可以是字符串、数字、布尔值或是实际的对象。如:
throw “an error occurred”;
throw 5007;throw true;
throw new Object();
throw new Error();
throw new Error(“error”);
throw new Error(10001,”error”);
优化javascript
javascript是作为源代码下载,然后浏览器对其进行 解释的(不存在编译问题),因此javascript的性能就体现在速度方法,而速度又被分割成两部分:下载时间和执行速度
1、 下载时间: 使用java等其他语言我们可以不必考虑100个字符长的变量名及大量的注释.因为这些在编译后名称会被替换掉,注释也会被自动删除,但javascript开发人员,就没有这么爽了!
增加下载时间的关键因素是脚本所包含的字节数.
记住一个关键数字1160;这是能放入单个TCP-IP包中的字节数。最好能将每个javascript文件都保持在1160字节以下以获取最优的下载时间
减小代码下载的时间方法:
ü 删除注释
ü 删除制表符和空格
ü 删除所有的换行
ü 替换变量名
如:function dosomthing(sname,sage,scity)
=> function dosomthing(a,b,c)
推荐一个工具:ECMASCript Cruncher
下载地址:http://www.saltstorm.net/depo/esc/
如:C:\>cscript C:\ESC-1.14\ESC.wsf -l [0-4] -ow outputfile.js inputfile1.js [inputfile2.js]
说明:
cscript是windows shell脚本解释程序。
[0-4]是一个压缩等级
-ow 表示下一个参数是优化后输出的文件名,最后剩下的是要优化的js文件
ESC支持以下四个优化等级
等级 | 描述 |
0 | 不改变脚本,将多个文件合并到单个文件 |
1 | 删除所有注释 |
2 | 除等级1个,再删除额外的制表符和空格 |
3 | 除等级2外,再删除换行 |
4 | 除等级3个,再进行变量名替换 |
|
|
其他减少字节数的方法
ü 替换布尔值
相对于比较来说:true等于1,false等于0.因此脚本包含的字面量true都可以用1来替换,而false可以用0替换
如:var bFound=false;
for(var i=0;i<aTest.length && !bFound;i++)
{
bFound = true;
}
可以替换成:
var bFound =0;
for(var i=0;i<aTest.length && !bFound;i++)
{
bFound = 1;
}
缩短否定检测
如:
if (oTest!=undefined){}
if (oTest != null){}
Þ if (oTest!=false){} if (!oTest){ //do something}
ü 使用数组和对象字面量
var aTest = new Array(); => var aTest = [ ]; //相当于新建一个空数组
var oTest = new Object();
Þ oTest = {};
如:
var oCar = new Object();
oCar.color = “red”;
oCar.name=“mycar”;
=>
var oCar = {color:”red”,name:”mycar”}
} 执行时间
1、关注范围
ü 使用局部变量
如果直接使用变量而不事先使用var进行声明,变量就会创建在window范围内,解释程序就会搜索整个范围树
如:<SCRIPT LANGUAGE="JavaScript">
<!--
function mytest()
{
svar = "Micro";
alert(svar);
}
mytest();
alert("ok"+svar);
//-->
</SCRIPT>
} 避免with语句
范围越少,速度越快,这是不使用with语句的原因
如:alert(document.title);
alert(document.body.tagName);
alert(document..location);
替换成:with(document)
{
alert(title);
alert(body.tagName);
alert(location);
}
最好避免使用with语句,减少的代码长度并不能弥补损失的性能
} 计算机科学基础
ü 选择正确的算法
1、反转循环.速度要块
for(var i=0;i<aValues.length;i++)
{ }
=>
for(var i=aValues.length;i>=0;i--)
{ }
} 翻转循环
如:var i=0;
while(i<aValues.length)
{
i++;
}
=>:do{
i++
} while(i>=0)
Þ var i=aValues.length-1;
do{
i--;
}while(i>=0)
u 其他
ü 避免字符串连结,通过自己的封装的方法
ü 优先使用内置方法
ü 存储常用的值
ü 节约使用DOM