精湛的企业网站建设,最新足球赛事,WordPress文章更新器,电子商务网站建设案例分析关注[前端小讴]#xff0c;阅读更多原创技术文章 错误处理
相关代码 →
try/catch 语句
ES3 新增了try/catch语句#xff0c;基本语法与 Java 中的 try/catch 一样
try {// 可能出错的代码const a 3;a 4;
} catch (error) {// 出错时执行的代码console.log(An er… 关注[前端小讴]原创技术文章 错误处理
相关代码 →
try/catch 语句
ES3 新增了try/catch语句基本语法与 Java 中的 try/catch 一样
try {// 可能出错的代码const a 3;a 4;
} catch (error) {// 出错时执行的代码console.log(An error happened!); // An error happened!
}try 块中有代码发生错误代码会立即退出执行并跳到 catch 块中所有浏览器都支持错误对象的message和name属性
try {const a 3;a 4;
} catch (error) {console.log(error);/* TypeError: Assignment to constant variable.at Object.anonymous (c:\Users\43577\Desktop\工作\my_project\my_demos\javascript高级程序设计第四版\第21章 错误处理与调试\21.2.错误处理.js:13:5)at Module._compile (internal/modules/cjs/loader.js:1085:14)at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)at Module.load (internal/modules/cjs/loader.js:950:32)at Function.Module._load (internal/modules/cjs/loader.js:790:12)at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:75:12)at internal/main/run_main_module.js:17:47*/console.log(error.name); // TypeError类型错误console.log(error.message); // Assignment to constant variable.常量被赋值
}finally 子句
try/catch 中可选的 finally 子句始终运行二者均无法阻止finally 块执行 try 中代码运行完会执行 finally 的代码出错并执行 catch 中代码仍会执行 finally 的代码
// finally 子句
try {console.log(1); // 1执行
} catch (error) {console.log(2); // 不执行
} finally {console.log(3); // 3执行
}try {const a 3;a 4;
} catch (error) {console.log(2); // 2try出错执行catch
} finally {console.log(3); // 3仍执行
}代码中包含 finally try 或 catch 中的 return 会被忽略
console.log((function testFinally() {try {console.log(try); // try非return语句不受影响return 1;} catch (error) {return 2;} finally {console.log(finally); // finallyreturn 3;}})()
); // 3包含finally语句try或catch中的return会被忽略错误类型
Error基类型InternalError底层引擎异常时如递归过多导致的栈溢出EvalError使用 eval()异常时但浏览器不会总抛出 EvalErrorRangeError数值越界时ReferenceError找不到对象时SyntaxError给 eval()传入的字符串包含语法错误时TypeError最常见 变量不是预期类型时访问不存在的方法时
new Array(-1); // RangeError: Invalid array length
let obj x; // ReferenceError: x is not defined
eval(12); // SyntaxError: Invalid left-hand side expression in postfix operation
console.log(a in abc); // TypeError: Cannot use in operator to search for a in abc
Function.prototype.toString().call(name); // TypeError: Function.prototype.toString(...).call is not a function可以使用instanceof操作符在 catch 块中确定错误类型
try {const a 3;a 4;
} catch (error) {if (error instanceof TypeError) {console.log(TypeError!);}
} // TypeError!
try {new Array(-1);
} catch (error) {if (error instanceof RangeError) {console.log(RangeError!);}
} // RangeError!try/catch 的用法
浏览器认为 try/catch 中发生的错误已被处理不会再报错try/catch 最好使用在开发者无法控制但有可能出现错误上如不便修改代码的第三方 js 库最好使用 try/catch 把函数调用包起来
抛出错误 throw 操作符可在任何时候抛出自定义错误 throw 操作符必须有值类型不限 // throw 12345; // Uncaught 12345后续代码停止
// throw Hello world; // Uncaught Hello world后续代码停止
// throw true; // Uncaught true后续代码停止
// throw { name: JS }; // Uncaught {name: JS}后续代码停止使用 throw 时代码立即停止try/catch 语句中捕获了抛出的值时除外 try {throw 123;
} catch (error) {console.log(123);
} // 123
console.log(5); // 5throw被try/catch捕获后续代码照常可通过内置错误类型模拟浏览器错误
// throw new SyntaxError; // Uncaught SyntaxError
// throw new InternalError; // Uncaught InternalError
// throw new TypeError; // Uncaught TypeError
// throw new RangeError; // Uncaught RangeError
// throw new EvalError; // Uncaught EvalError
// throw new URIError; // Uncaught URIError
// throw new RefenceError; // Uncaught RefenceError可通过继承 Error创建自定义错误类型创建时需提供 name 和 message 属性
class CustomError extends Error {constructor(message) {super(message); // super调用父类构造函数手动给父类传参并将返回值赋给子类中的thisthis.name CustomError;this.message message;}
}
// throw new CustomError(My message); // CustomError: My message何时抛出错误
已知函数无法正确执行时浏览器会自动抛出错误复杂的程序很难找到错误原因适当创建自定义错误可有效提高代码的可维护性应仔细评估每个函数尤其可能导致失败的情形
function process(values) {if (!(values instanceof Array)) {throw new Error(process(): Argument must be an Array.);}values.sort(); // 如果values不是数组则浏览器会报错。因此在此句之前判断参数类型且用自定义错误可有效提高代码可维护性for (let value of values) {if (value 100) {return value;}}return -1;
}
// process(1); // Error: process(): Argument must be an Array.
// process(1); // TypeError: values.sort is not a function如果没有throw代码段的结果抛出错误与 try/catch
捕获错误的目的是阻止浏览器以其默认方式响应抛出错误的目的是提供有关其发生原因的说明应该在明确接下来做什么时捕获错误
error 事件
没有被 try/catch 捕获的错误会在浏览器 window 对象上触发 error 事件 onerror 事件处理程序中任何浏览器都不传入 event 对象传入 3 个参数错误消息、发生错误的 URL、发生错误的行号任何错误发生都会触发 error 事件并执行事件的处理程序浏览器默认行为会生效可以返回 false 来阻止浏览器默认报告错误的行为
window.onerror (message, url, line) {console.log(message);return false; // 阻止浏览器默认报告错误
};图片中 src 属性的 url 没有返回可识别的图片格式也会触发 error 事件
const image new Image();
image.addEventListener(load, (event) {console.log(Image loaded!);
});
image.addEventListener(error, (event) {console.log(Image not loaded!);
});
image.src a.jpg; // Image not loaded!识别错误
类型转换错误 主要原因是使用了会自动改变某个值的数据类型的草错付或语言构造 在比较过程中应使用严格相等和严格不等避免错误 console.log(5 5); // true
console.log(5 5); // false数据类型不同
console.log(1 true); // true
console.log(1 true); // false数据类型不同在 if、for、while 等流程控制语句中应坚持使用布尔值作为条件避免错误 function concat(str1, str2, str3) {let result str1 str2;if (str3) {result str3;}return result;
}
console.log(concat(1, 2, 0)); // 120
console.log(concat(1, 2)); // 12str3是undifined转化为false
console.log(concat(1, 2, 0)); // 12str3是数值0转化为false与预期不符function concat(str1, str2, str3) {let result str1 str2;if (str3 ! undefined) {result str3;}return result;
}
console.log(concat(1, 2, 03)); // 120
console.log(concat(1, 2)); // 12str3 是 undifined转化为 false
console.log(concat(1, 2, 0)); // 120达到预期数据类型错误 JS 是松散类型其变量和函数参数都不能保证数据类型 原始类型的值使用typeof检测 function getQueryString(url) {const pos url.indexOf(?); // indexOf是字符串才有的方法if (pos 1) {console.log(url.substring(pos 1)); // substring是字符串才有的方法return;}console.log(not has ?);
}
// getQueryString(123); // TypeError: url.indexOf is not a functionfunction getQueryString2(url) {if (typeof url string) {// 确保不会因为参数是非字符串值而报错const pos url.indexOf(?);if (pos 1) {console.log(url.substring(pos 1));return;}console.log(not has ?);}
}
getQueryString2(123); // 不打印
getQueryString2(123); // not has ?
getQueryString2(https://www.baidu.com?keyWorderror); // keyWorderror对象值使用instanceof检测 function reverseSort(values) {if (values) {// 不可取values为true的情况很多values.sort();values.reverse();}
}
// reverseSort(1); // TypeError: values.sort is not a functionfunction reverseSort2(values) {if (values ! null) {// 不可取values不为null的情况很多values.sort();values.reverse();}
}
// reverseSort2(1); // TypeError: values.sort is not a functionfunction reverseSort3(values) {if (typeof values.sort function) {// 不可取假如values有sort()方法但不是数组则会报错values.sort();values.reverse();}
}
// reverseSort3({
// sort: () {
// console.log(3);
// },
// }); // 先values.sort()打印3后报错TypeError: values.reverse is not a functionfunction reverseSort4(values) {if (values instanceof Array) {// 可取确保values是Array的实例values.sort();values.reverse();}
}
let val1 1;
let val2 [1, 2];
reverseSort4(val1);
reverseSort4(val2);
console.log(val1); // 1
console.log(val2); // [2,1]通信错误
对于 url 的查询字符串都要通过encodeURIComponent()以确保编码合适
let url https://www.baidu.com?keyWordhttps://www.taobao.com; // url格式不正确
function addQueryStringArg(url, name, value) {if (url.indexOf(?) -1) {url ?;} else {url ;}url ${encodeURIComponent(name)}${encodeURIComponent(value)};return url;
}
let url2 addQueryStringArg(https://www.baidu.com,keyWord,https://www.taobao.com
);
console.log(url2); // https://www.baidu.com?keyWordhttps%3A%2F%2Fwww.taobao.com与服务器通信的正确url格式区分重大与非重大错误
非重大错误 不影响用户主要任务只影响页面中某个部分可恢复重复操作可能成功 重大错误 程序无法继续运行严重影响用户的主要目标会导致其他错误 程序某个部分的错误不应该影响其他部分模块初始化时可在 for 循环中加入 try/catch 语句避免某一模块初始化时发生错误影响其他模块
let mods [{name: mod1,init: () {const a 1;a 2;console.log(mod1 init);}, // mod1的init方法里有错误},{name: mod2,init: () {console.log(mod2 init);},},
];
for (let mod of mods) {// mod.init(); // 不好只要有一个mod的init方法出错影响后续try {mod.init(); // mod2 initmod2照常运行} catch (error) {console.log(error); // TypeError: Assignment to constant variable.}
}总结 问点
错误对象中的哪些属性在全部浏览器中都向用户显示finally 对 try 或 catch 中的非 return 语句和 return 语句分别有什么影响请举例说明有哪些常见错误类型及其出现的原因请写一段代码在 try/catch 块中确定错误的类型throw 操作符必须有值嘛需要什么数据类型的值如何才能既使用该操作符又不影响后续代码执行写一段代码通过继承 Error 创建一个自定义的错误类型创建其实例并用 throw 将其抛出写一段代码在一个函数里通过创建自定义错误类型提高其可维护性常见的类型转换错误有哪些分别该如何避免呢应分别怎样检测以避免原始值和对象值在函数传参时可能发生的数据类型错误写一个方法处理与服务器通信的 url 的正确格式写一段代码用 for 循环模拟模块初始化某一模块加载时发生错误但不影响后续模块