var s = null; var len = s.length; // TypeError:null变量没有length属性
对于这种错误,要修复程序
程序可能遇到无法预测的异常情况而报错,例如,网络连接中断,读取不存在的文件,没有操作权限等。
对于这种错误,我们需要处理它,并可能需要给用户反馈。
int fd = open("/path/to/file", O_RDONLY); if (fd == -1) { printf("Error when open file!"); } else { // TODO }
通过错误码返回错误,就需要约定什么是正确的返回值,什么是错误的返回值。上面的open()
函数约定返回-1
表示错误。
显然,这种用错误码表示错误在编写程序时十分不便。
'use strict'; var r1, r2, s = null; try { r1 = s.length; // 此处应产生错误 r2 = 100; // 该语句不会执行 } catch (e) { console.log('出错了:' + e); } finally { console.log('finally'); } console.log('r1 = ' + r1); // r1应为undefined console.log('r2 = ' + r2); // r2应为undefined >>> 出错了:TypeError: Cannot read property 'length' of null finally r1 = undefined r2 = undefined
当代码块被
try { ... }
包裹的时候,就表示这部分代码执行过程中可能会发生错误,一旦发生错误,就不再继续执行后续代码,转而跳到catch
块。catch (e) { ... }
包裹的代码就是错误处理代码,变量e
表示捕获到的错误。最后,无论有没有错误,finally
一定会被执行。
有错误发生时,执行流程像这样:
try { ... }
的代码;catch (e) { ... }
代码;finally { ... }
代码。而没有错误发生时,执行流程像这样:
try { ... }
的代码;catch (e) { ... }
代码不会被执行;finally { ... }
代码。最后请注意,catch
和finally
可以不必都出现。
try { ... } catch (e) { ... //错误处理 }
var txt=""; function message() { try { adddlert("Welcome guest!"); } catch(err) { txt="本页有一个错误。\n\n"; txt+="错误描述:" + err.message + "\n\n"; txt+="点击确定继续。\n\n"; alert(txt); } }
try { ... } finally { ... }
JavaScript有一个标准的Error
对象表示错误,还有从Error
派生的TypeError
、ReferenceError
等错误对象。我们在处理错误时,可以通过catch(e)
捕获的变量e
访问错误对象:
try { ... } catch (e) { if (e instanceof TypeError) { alert('Type error!'); } else if (e instanceof Error) { alert(e.message); } else { alert('Error: ' + e); } }
使用变量e
是一个习惯用法,也可以以其他变量名命名,如catch(ex)
程序也可以主动抛出一个错误,让执行流程直接跳转到catch
块。抛出错误使用throw
语句
'use strict'; var r, n, s; try { s = prompt('请输入一个数字'); n = parseInt(s); if (isNaN(n)) { throw new Error('输入错误'); } // 计算平方: r = n * n; console.log(n + ' * ' + n + ' = ' + r); } catch (e) { console.log('出错了:' + e); }
<!DOCTYPE html> <html> <body> <script> function myFunction() { try { var x=document.getElementById("demo").value; if(x=="") throw "值为空"; if(isNaN(x)) throw "不是数字"; if(x>10) throw "太大"; if(x<5) throw "太小"; } catch(err) { var y=document.getElementById("mess"); y.innerHTML="错误:" + err + "。"; } } </script> <h1>我的第一个 JavaScript 程序</h1> <p>请输入 5 到 10 之间的数字:</p> <input id="demo" type="text"> <button type="button" onclick="myFunction()">测试输入值</button> <p id="mess"></p> </body> </html>
当我们用catch捕获错误时,一定要编写错误处理语句:
var n = 0, s; try { n = s.length; } catch (e) { console.log(e); } console.log(n);
哪怕仅仅把错误打印出来,也不要什么也不干:
var n = 0, s; try { n = s.length; } catch (e) { } console.log(n);
因为catch到错误却什么都不执行,就不知道程序执行过程中到底有没有发生错误。
处理错误时,请不要简单粗暴地用alert()
把错误显示给用户。
编写JavaScript代码时,我们要时刻牢记,JavaScript引擎是一个事件驱动的执行引擎,代码总是以单线程执行,而回调函数的执行需要等到下一个满足条件的事件出现后,才会被执行。
例如,setTimeout()
函数可以传入回调函数,并在指定若干毫秒后执行:
function printTime() { console.log('It is time!'); } setTimeout(printTime, 1000); console.log('done');
上面的代码会先打印done
,1秒后才会打印It is time!
。
如果printTime()
函数内部发生了错误,我们试图用try包裹setTimeout()
是无效的:
'use strict'; function printTime() { throw new Error(); } try { setTimeout(printTime, 1000); console.log('done'); } catch (e) { console.log('error'); } >>> done
JavaScript 可用来在数据被送往服务器前对 HTML 表单中的这些输入数据进行验证。
被 JavaScript 验证的这些典型的表单数据有:
下面的函数用来检查用户是否已填写表单中的必填(或必选)项目。假如必填或必选项为空,那么警告框会弹出,并且函数的返回值为 false,否则函数的返回值则为 true(意味着数据没有问题):
function validate_required(field,alerttxt) { with (field) { if (value==null||value=="") {alert(alerttxt);return false} else {return true} } }
下面是连同 HTML 表单的代码:
<html> <head> <script type="text/javascript"> function validate_required(field,alerttxt) { with (field) { if (value==null||value=="") {alert(alerttxt);return false} else {return true} } } function validate_form(thisform) { with (thisform) { if (validate_required(email,"Email must be filled out!")==false) {email.focus();return false} } } </script> </head> <body> <form action="submitpage.htm" onsubmit="return validate_form(this)" method="post"> Email: <input type="text" name="email" size="30"> <input type="submit" value="Submit"> </form> </body> </html>
下面的函数检查输入的数据是否符合电子邮件地址的基本语法。
意思就是说,输入的数据必须包含 @ 符号和点号(.)。同时,@ 不可以是邮件地址的首字符,并且 @ 之后需有至少一个点号:
function validate_email(field,alerttxt) { with (field) { apos=value.indexOf("@") dotpos=value.lastIndexOf(".") if (apos<1||dotpos-apos<2) {alert(alerttxt);return false} else {return true} } }
下面是连同 HTML 表单的完整代码:
<html> <head> <script type="text/javascript"> function validate_email(field,alerttxt) { with (field) { apos=value.indexOf("@") dotpos=value.lastIndexOf(".") if (apos<1||dotpos-apos<2) {alert(alerttxt);return false} else {return true} } } function validate_form(thisform) { with (thisform) { if (validate_email(email,"Not a valid e-mail address!")==false) {email.focus();return false} } } </script> </head> <body> <form action="submitpage.htm"onsubmit="return validate_form(this);" method="post"> Email: <input type="text" name="email" size="30"> <input type="submit" value="Submit"> </form> </body> </html>