Javascript的错误主要是语法错误和运行时的错误,前者在代码解析时就会出错,影响程序的运行。后者称为异常,影响它所运行的线程。下面就Javascript常见错误进行分析
1.常见的错误和异常
i.拼写错误
任何开发者在编写javascript程序时都犯过拼写错误,例如将document.getElementsByTagName()写成document.getElementByTagName(),将getElementByid()拼写成getElementByID()等。还有一些大小写的问题。例如:
If(photo.href){ var url= photo.href;}
以上将关键字if拼写成If,导致语法错误,这种拼写错误通常可以通过编写软件高亮显示出来。而另外一些变量上的错误拼写错误则稍微马轩写,需要开发的人耐心检查,例如:
var PhotoAlbum = "isaac"; var PhotoAlbumWife = "fresheggs"; alert("the photo:/n"+ PhotoAbulm + "and" + PhotoAlbumWife);
会提示PhotoAbulm is not defined(变量未定义。)通过检查我们发现,定义了“PhotoAlbum”而未定义PhotoAbulm。
ii.访问未存在的变量。
最规范的变量定义都是通过var,但是javascript允许不使用关键字而直接定义变量。比如以下代码都是合法的
var isaac = "husband of fresheggs"; fresheggs = "wife of isaac";
这就无形中给检查代码增加了麻烦,像下面几行代码是比较容易发现的,浏览器也会相应的给出变量不存在的位置。
var isaac = "husband of fresheggs"; alert(fresheggs); fresheggs = "wife of isaac";
但是很多时候,错误是十分隐蔽的
<script language="javascript"> var oInputField; var oPopDiv; var oColorsUl; var aColors = ["red", "green", "blue", "magenta", "yellow", "cornfloewrblue"]; function clearColors() { for (var i = oColorsUl.childNodes.length - 1; i >= 0; i--) oColorsUl.removeChild(oColorsUl.childNodes[i]); oPopDiv.className = "hide"; } function setColors(the_clors) { oInputField = document.forms["myForm1"].colors; oPopDiv = document.getElementById("popup"); oColorsUl = document.getElementById("colors_ul"); clearColors(); oPopDiv.className = "show"; var oLi; for (var i = 0; i < aColors.length; i++) { oLi = document.createElement("li"); oColorsUl.appendChild(oLi); oLi.appendChild(document.createTextNode(the_colors[i])); oLi.onmouSEOver = function() { this.className = "mouseOver"; } oLi.onmouseout = function() { this.className = "mouseOut"; } oLi.onclick = function() { oInputField.value = this.firstChild.nodeValue; clearColors(); } } } </script><form method="post" name="myForm1"> Color: <input type="text" name="colors" id="colors" onkeyup="setColors(aColors);" /> </form> <div id="popup"> <ul id="colors_ul"></ul> </div>
浏览器告知:Uncaught ReferenceError: the_colors is not defined the_colors变量未定义,仔细检查32行
oLi.appendChild(document.createTextNode(the_colors[i]));
确没有错误,其实错误在第22行拼写错误。这样提示和错误不符大大增加了检查的难度。
function setColors(the_clors)
iii.括号不匹配
编写较长的逻辑关系代码时,常常需要反复的使用花括弧和小括弧,很多时候因为删除某些代码导致括号和括号后的个数不匹配。
function testPic(x, start, end) { if (x <= end && x >= start) { if (x == start) { alert(x + " is the start of the range"); } if (x == end) { alert(x + " is the end of the range"); } if (x != start && x != end) { alert(x + " is in the range"); } else { alert(x + " is not in the range"); } } testPic(7, 5, 8);
错误报告10行缺少},但行数不一定在10行。
正确代码
function testPic(x, start, end) { if (x <= end && x >= start) { if (x == start) { alert(x + " is the start of the range"); } if (x == end) { alert(x + " is the end of the range"); } if (x != start && x != end) { alert(x + " is in the range"); } } else { alert(x + " is not in the range"); } } testPic(7, 5, 8);
从正确的代码可以看到,要避免括号遗漏的最有效办法是养成规范的编码习惯,适当应用tab 空行等
iiii.字符串和变量连接错误
javascript在输出结果时常常需要将字符串和变量连接,因此加号和引号都很多,容易错漏
father = "isaac";mother = "fresheggs";child = "none";family = father+" "+mother+" "child;
如上面的代码,在child前边漏掉了+号,导致程序错误
还有一种典型的连接错误就是javascript的类型转化。如下代码
a = 10;b = 20;c = 30;alert("a+b+c="+a+b+c);
执行结果102030显然不是我们所想要的结果,解决上述问题的办法就是利用括号把数值部分和文字串部门分别做处理,然后加起来。
a = 10;b = 20;c = 30;alert("a+b+c="+(a+b+c));
iiiii.等号与赋值混淆。
在条件判断中,常常会把等号==误写成赋值符号= ,这样的语法没有任何问题,javascript会把它处理成赋值是否成功来判断真假
if (isaac = "talking"){ fresheggs.hear();}
以上代码的执行结果是将变量isaac赋值为"talking",如果赋值成功,则执行花括弧中的fresheggs,但开发者的本意是
if (isaac == "talking"){ fresheggs.hear();}
即当isaac的变量值为"talking"时,执行fresheggs.hear();这样的问题在程序检查中是很难发现的
2.错误处理
i.用alert()和document.write()来监视变量值
在日常开发中,alert()和document.write()来监视变量值,恐怕是最常用和有些的解决的方法。
alert()在开发中会跳出目前的变量值,并中止程序的运行,直到点击确定后继续执行。document.write()方法则是输出变量值后继续执行程序,因为两者的执行方法不同,所以给开发者带来了选择上的技巧。
for(var i=0;i<aColors.length;i++)if(aColors[i].indexOf(oInputField.value)==0)aResult.push(aColors[i]);
为了检测传入aResult的值,常给if加入alert()方法来检测,如果值很多,最好使用document.write()方法来检测传入值,避免反复的进行确定
ii.使用onerro方法
当页面出现错误时,onerro事件使用window对象触发,告诉开发者哪出了错误。
<script language="javascript">window.onerror = function(){ alert("出错啦!");}</script></head><body onload="nonExistent()"></body>
利用window.onload引用一个不存在的函数引发异常,浏览器本身也出现了调试错误,要屏蔽错误信息,只需要在onerror函数后面加return true即可。
<script type="text/javascript">window.onerror = function(){ alert("出错啦!"); return true; //屏蔽系统事件}</script></head><body onload="nonExistent()"></body>
但是这样对处理错误没有任何帮助,其实onerror提供了三个参数确定错误性质
<script type="text/javascript">window.onerror = function(sMessage,sUrl,sLine){ alert("出错了:/n"+sMessage+"/n 地址:"+ sUrl +"/n行号:"+sLine); return true; //屏蔽系统事件}</script>
iii.使用try...catch语句找到错误
js中借鉴了java的try...catch方法,该语句会先运行try里边的方法,如果出现错误则跳转运行catch()里面的代码,如果有finnally,则无论是否错误都运行其后的代码
try...catch的语法如下:
try...catch的代码语法如下:try{ //代码}catch([exception]){ //如果try里面的代码有错,则运行}[finally{ //最后运行,无论是否出错}]
例子:使用try...catch语法找错误
<script type="text/javascript">try{ alert("this is an example"); alert(fresheggs);} catch(exception){ var sError = ""; for(var i in exception) sError += i + ":" + exception[i] + "/n"; alert(sError);}</script>
在以上语法中特意输出一个未定义的变量fresheggs,导致了异常,由此运行catch里面的代码,此时浏览器会跳出错误
通过try...catch能轻松的找到错误,但可惜的是该语句并不能很好的处理语法错误。
如下:try语句中出现了语法错误,而这个代码并没有运行catch中的代码。
<script type="text/javascript">try{ alert("this is an example") );} catch(exception){ var sError = ""; for(var i in exception) sError += i + ":" + exception[i] + "/n"; alert(sError);}</script>
3.使用调试器
尽管javascript不具有调试功能,但是我们借助ie或者Firefox浏览器的控制台或者调试插件能起到调试作用。
i.使用firefox错误控制台进行调试
使用firefox错误控制台,我们在页面中右键鼠标,审查元素,调到控制台,js选项就可以看到浏览器把页面运行的所有js错误信息都传到错误控制台上,单击每条信息就会打开对于的代码。
firefox错误调试平台比ie准确的多,在没有特殊需求的调试要求下,是个不错的选择。
ii.使用Microsoft Script debugger进行调试
http://www.microsoft.com/zh-cn/download/details.aspx?id=23992
iii.使用Venkman
在火狐浏览器中直接安装即可。
关于vankman 请参看http://jiangzhengjun.iteye.com/blog/481500一文。
4.javascript的优化
i.减缓代码的下载时间。web浏览器下载的是javascript的源码,其中包含的长变量名、注释、空格换行
新闻热点
疑难解答