一、Javascript常见的代码错误类型
Javascript错误分为两种:
(1)代码错误:这种错误浏览器会报错,可以根据错误类型去排错
(2)逻辑错误:这种错误浏览器不会报错,但是可以使用断点进行调试排错
ECMS中定义了以下七种错误类型,并在错误发生时抛出不同的错误对象。
- Error
Error是基类型,其他错误类型都是继承该类型,因此,所有错误类型都是共享相同的属性(所有错误对象上的方法都是这个默认类型定义的方法)。
浏览器很少会抛出Error类型的错误,该类型主要用于开发者抛出自定义错误。(如:throw new Error(输出错误信息))。拦截器/导航守卫中也经常会使用到. - SyntaxError(语法错误)
当错误的使用已经预定义的语法时会抛出此错误。
a.变量名不符合规范
b.缺少括号引发的语法错误
c.用let、const声明重复变量/常量
//a:变量名不符合规范
var 1s;//Uncaught SyntaxError: Invalid or unexpected token
var c=1;
//b:缺少括号引发的语法错误
console.log 'song')
VM180:1 Uncaught SyntaxError: Unexpected string
//c:用let、const声明重复变量/常量
const c=2;//Uncaught SyntaxError: Identifier 'c' has already been declared
- TypeError(类型错误)
当值不是预期数据类型、调用无效方法时都会抛出此错误。
a:new后面接字符串、数值、布尔值等(new后面应该接构造函数)
b:调用不存在的方法
//a:new后面接字符串、数值、布尔值等(new后面应该接构造函数)
new 'song';//Uncaught TypeError: "song" is not a constructor
new 12;//Uncaught TypeError: 12 is not a constructor
new true;//Uncaught TypeError: true is not a constructor
//b:调用不存在的方法
var obj={name:"song",sex:2,};
obj.play();//Uncaught TypeError: obj.play is not a function
- ReferenceError(引用错误)
当找不到变量的引用、在变量作用域范围之外使用变量、使用未声明的变量时、在暂时性死区期间使用变量时都会抛出此错误。
str=2;
let str=1;//Uncaught ReferenceError: Cannot access 'af' before initialization
- RangeError(范围错误)
数组的长度为负数、将变量设置在其限定的范围之外、将值传递给超出范围的方法、调用一个不会结束的递归函数时就会抛出此错误。
var a=new Array(-1);//Uncaught RangeError: Invalid array length
- URIError( URI 错误)
当 URI 的编码和解码出现问题时,会抛出 URIError。JavaScript 中的 URI 操作函数包括:decodeURI、decodeURIComponent 等。如果使用了错误的参数(无效字符),就会抛出 URIError。
decodeURI("%2");//Uncaught URIError: URI malformed
- EvalError(Eval 错误)
当 eval() 函数调用发生错误时,会抛出 EvalError。不过,当前的 JavaScript 引擎或 ECMAScript 规范不再抛出此错误。但是,为了向后兼容,它仍然是存在的。
补充:InternalError(内部错误)
非ECMAScript标准,请尽量不要在生产环境中使用它!
InternalError 对象表示出现在 JavaScript 引擎内部的错误(工作负载突然激增时:如当它有太多数据要处理并且堆栈增长超过其关键限制时)。示例场景通常为某些成分过大,例如:
"InternalError: too much recursion"(内部错误:递归过深)。
"InternalError: too many switch cases"(过多case子句);
"InternalError: too many parentheses in regular expression"(正则表达式中括号过多);
"InternalError: array initializer too large"(数组初始化器过大);
二、Javascript异常处理
1.异常处理语句
你可以用 throw 语句抛出一个异常,并且用 try…catch…finally 语句捕获处理它。
throw 语句
使用throw语句抛出一个异常。当你抛出异常,你规定一个含有值的表达式要被抛出。
throw expression;
你可以抛出任意表达式而不是特定一种类型的表达式。下面的代码抛出了几个不同类型的表达式:
throw "Error2"; // String type
throw 42; // Number type
throw true; // Boolean type
throw {toString: function() { return "I'm an object!"; } };
try…catch 语句
如果 try 代码块中的语句(或者try 代码块中调用的方法)一旦抛出了异常,那么执行流程会立即进入catch 代码块。如果 try 代码块没有抛出异常,catch 代码块就会被跳过。
//1.自定义一个异常处理函数
function logMyErrors (message){
this.message=message;
this.name="logMyErrors";
alert(message);
};
//2.自定义一段处理程序,报错的话抛出异常
function getMonthName(mo) {
mo = mo - 1; // Adjust month number for array index (1 = Jan, 12 = Dec)
var months = ["Jan","Feb","Mar","Apr","May","Jun","Jul",
"Aug","Sep","Oct","Nov","Dec"];
if (months[mo]) {
return months[mo];
} else {
throw "InvalidMonthNo"; //throw keyword is used here
}
}
//3.在try语句块中执行那段处理程序,用catch语句捕获异常信息作为参数传递给异常处理函数处理
try { // statements to try
monthName = getMonthName(19); // function could throw exception
}
catch (e) {
monthName = "unknown";
logMyErrors(e); // pass exception object to error handler -> your own function
}
finally语句
finally 代码块总会紧跟在 try 和 catch 代码块之后执行,但会在 try 和 catch 代码块之后的其他代码之前执行。
finally块无论是否抛出异常都会执行。如果抛出了一个异常,就算没有异常处理,finally块里的语句也会执行。
你可以用finally块来令你的脚本在异常发生时优雅地退出;
try {
//需要运行的代码 使用throw语句抛错。
}catch (err) {
//捕获错误代码
}finally{
//无论try和catch的结果如何,都正常执行的代码
}
ps:catch 和 finally 语句不是必须的,但一条 try 语句中至少使用一个catch 或 finally 语句。