JavaScript 错误
在我们的程序中,事情并非一帆风顺。
特别是在某些情况下,我们可能希望在停止程序或在发生不良状况时通知用户。例如:
程序试图打开一个不存在的文件。
网络连接断开。
用户进行了无效的输入。
在所有的这些情况下,我们作为程序员都会产生错误,或者让编程引擎为我们创建一些错误。
在创建错误之后,我们可以向用户通知消息,或者可以完全停止执行。
JavaScript 中有什么错误?
JavaScript 中的错误是一个对象,随后被抛出,用以终止程序。
要在 JavaScript 中创建新错误,我们调用相应的构造函数。例如,要创建一个新的通用错误,可以执行以下操作:
const err = new Error("Something bad happened!");
创建错误对象时,也可以省略关键字 new:
const err = Error("Something bad happened!");
创建后,错误对象将显示三个属性:
- message:带有错误信息的字符串。
- name:错误的类型。
- stack:函数执行的栈跟踪。
例如,如果我们用适当的消息创建一个新的 TypeError 对象,则 message 将携带实际的错误字符串,而 name 则为 TypeError:
const wrongType = TypeError("Wrong type given, expected number");
wrongType.message; // "Wrong type given, expected number"
wrongType.name; // "TypeError"
Firefox 还实现了一堆非标准属性,例如 columnNumber,filename 和 lineNumber。
JavaScript 抛出(throw)错误
当错误发生时,当事情出问题时,JavaScript 引擎通常会停止,并生成一个错误消息。
描述这种情况的技术术语是:JavaScript 将抛出一个错误。
JavaScript try 和 catch
try 语句允许我们定义在执行时进行错误测试的代码块。
catch 语句允许我们定义当 try 代码块发生错误时,所执行的代码块。
JavaScript 语句 try 和 catch 是成对出现的。
try {
... //异常的抛出
} catch(e) {
... //异常的捕获与处理
} finally {
... //结束处理
}
举例说明:在下面的例子中,我们故意在 try 块的代码中写了一个错字。
catch 块会捕捉到 try 块中的错误,并执行代码来处理它。
var txt="";
function message()
{
try {
adddlert("Welcome guest!");
} catch(err) {
txt="本页有一个错误。\n\n";
txt+="错误描述:" + err.message + "\n\n";
txt+="点击确定继续。\n\n";
alert(txt);
}
}
Throw 语句
throw 语句允许我们创建自定义错误。
正确的技术术语是:创建或抛出异常(exception)。
如果把 throw 与 try 和 catch 一起使用,那么您能够控制程序流,并生成自定义的错误消息。
举例说明:本例检测输入变量的值。如果值是错误的,会抛出一个异常(错误)。catch 会捕捉到这个错误,并显示一段自定义的错误消息:
function myFunction() {
var message, x;
message = document.getElementById("message");
message.innerHTML = "";
x = document.getElementById("demo").value;
try {
if(x == "") throw "值为空";
if(isNaN(x)) throw "不是数字";
x = Number(x);
if(x < 5) throw "太小";
if(x > 10) throw "太大";
}
catch(err) {
message.innerHTML = "错误: " + err;
}
}
常规函数的错误处理
同步代码的执行顺序与写入顺序相同。我们再看一下前面的例子:
function toUppercase(string) {
if (typeof string !== "string") {
throw TypeError("参数类型需要是 string 的");
}
return string.toUpperCase();
}
toUppercase(4);
在这里,引擎调用并执行toUppercase。 所有这些都是同步发生的。 要捕获同步函数引发的异常,我们可以使用try/catch/finally:
try {
toUppercase(4);
} catch (error) {
console.error(error.message);
} finally {
}
使用 generator 函数来处理错误
JavaScript中的生成器函数是一种特殊的函数。除了在其内部作用域和使用者之间提供双向通信通道之外,还可以随意暂停和恢复。
要创建一个生成器函数,我们在function关键字后面放一个*:
function* generate() {
//
}
在函数内可以使用yield返回值:
function* generate() {
yield 33;
yield 99;
}
生成器函数的返回值是一个迭代器对象(iterator object)。要从生成器中提取值,我们可以使用两种方法:
使用 next() 方法
通过 for…of 遍历
如下所示,要想在生成器中获取值,我们可以这样做:
function* generate() {
yield 33;
yield 99;
}
const go = generate();
const firstStep = go.next().value; // 33
const secondStep = go.next().value; // 99
成器也可以采用其他方法工作:它们可以接收调用者返回的值和异常。
除了next()之外,从生成器返回的迭代器对象还具有throw()方法。使用这种方法,我们可以通过向生成器中注入一个异常来停止程序
function* generate() {
yield 33;
yield 99;
}
const go = generate();
const firstStep = go.next().value; // 33
go.throw(Error("我要结束你!"));
const secondStep = go.next().value; // 这里会抛出异常
要获取此错误,可以在生成器函数中使用 try/catch/finally:
function* generate() {
try {
yield 33;
yield 99;
} catch (error) {
console.error(error.message);
}
}
下面这个事例是使用 for…of 来获取 生成器函数中的值:
function* generate() {
yield 33;
yield 99;
throw Error("我要结束你!")
}
try {
for (const value of generate()) {
console.log(value)
}
} catch (error) {
console.log(error.message)
}
/* 输出:
33
99
我要结束你!
*/