本文深入解析JavaScript中的错误捕获机制。从Error对象的属性与七种内置错误类型入手,详细讲解throw语句的用法及try-catch-finally的标准结构。重点探讨finally块的返回值覆盖规则、try-catch对V8引擎优化的影响,以及window.onerror的全局监听。最后对比Promise中reject与throw的行为差异,并介绍Vue的异常捕获配置,帮助开发者构建健壮的代码。
前言
由于JavaScript引擎采用单线程执行模型,一旦代码运行过程中出现未处理的异常,引擎通常会立即停止后续代码的执行,并抛出相应的错误信息。因此,针对那些可以预见的异常情况,开发者应当实施有效的捕获策略,以便向用户或开发人员展示清晰、准确的错误提示,从而提升用户体验和调试效率。
Error 对象
当程序在运行阶段发生错误时,JavaScript引擎会抛出一个Error类的实例对象。
该错误对象主要包含两个关键属性:
- err.name:用于标识错误的名称或具体类型。
- err.message:提供关于错误的具体描述信息。
创建一个Error
new Error([message[,fileName[,lineNumber]]])
JavaScript标准中定义了以下7种内置的错误类型:
- Error
- EvalError
- RangeError
- ReferenceError
- SyntaxError
- TypeError
- URIError
throw
部分JavaScript代码虽然在语法上完全正确,但可能存在逻辑缺陷。对于这类逻辑错误,JavaScript引擎默认不会抛出异常。此时,开发者可以手动创建Error对象的实例,并利用throw语句主动抛出异常,以便在代码中更有针对性地处理特定错误。其基本语法格式如下:
throw new Error("errorstatements")
try…catch…finally
- try 可能发生异常的代码
- catch(error) 发生错误执行的代码
- finally 无论如何都会执行的代码
try语句支持以下三种声明形式:
- try...catch
- try...finally
- try...catch...finally
finally 的规则
如果在finally代码块中抛出异常,该异常将覆盖try或catch块中原本抛出的异常信息。
try {
try {
throw new Error('can not find it1');
} finally {
throw new Error('can not find it2');
}
} catch (err) {
console.log(err.message);
}
// can not find it2
如果finally代码块中返回了一个值,那么整个try-catch-finally语句块的返回值将变为该值,无论try或catch中是否有return语句。这一规则同样适用于catch块中抛出的异常。
function test() {
try {
throw new Error('can not find it1');
return 1;
} catch (err) {
throw new Error('can not find it2');
return 2;
} finally {
return 3;
}
}
console.log(test()); // 3
Try / Catch 性能
使用try/catch语句是一种众所周知的反优化模式。
在V8引擎(其他JavaScript引擎也可能存在类似情况)中,如果函数内部包含try/catch语句,V8编译器将无法对该函数进行优化处理。
window.onerror
通过为window.onerror注册一个事件监听函数,可以捕获程序中其他代码产生的、未被try-catch处理的异常。
window.onerror = function (message, source, lineno, colno, error) { }
- message:异常信息(字符串)
- source:发生异常的脚本URL(字符串)
- lineno:发生异常的行号(数字)
- colno:发生异常的列号(数字)
- error:Error对象(对象)
Promise 中的异常
Promise 中抛出异常
- new Promise((resolve,reject)=>{ reject(); })
- Promise.resolve().then((resolve,reject)=>{ reject(); });
- Promise.reject();
- throw expression;
Promise中捕捉异常
- promiseObj.then(undefined, (err)=>{ catch_statements });
- promiseObj.catch((exception)=>{ catch_statements })
注意
在JavaScript函数中,只有return、yield或throw语句会中断函数的执行流程,而reject调用不会阻止代码继续向下执行。
示例:
没有 return 的 reject
Promise.resolve()
.then(() => {
console.log('before excute reject');
reject(new Error('throw error'));
console.log('after excute reject');
})
.catch((err) => {
console.log(err.message);
});
// before excute reject
// throw error
// after excute reject
用了 return 的 reject
Promise.resolve()
.then(() => {
console.log('before excute reject');
return reject(new Error('throw error'));
console.log('after excute reject'); //*** 区别在这里,return 的话这里不会执行了
})
.catch((err) => {
console.log(err.message);
});
// before excute reject
// throw error
Vue 的异常捕获
Vue.config.errorHandler = (err, vm, info) => {
console.error("通过vue errorHandler捕获的错误");
console.error(err);
console.error(vm);
console.error(info);
};
总结
到此这篇关于JavaScript基础入门之错误捕获机制的文章就介绍到这了,更多相关js错误捕获机制内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!