javascript中提供了try-catch块的规定。尽管使用Java或任何其他语言进行错误处理是强制性的,但我看不到有人在javascript中更大程度地使用它们。这不是一个好习惯,还是我们在javascript中不需要它们?
javascript中提供了try-catch块的规定。尽管使用Java或任何其他语言进行错误处理是强制性的,但我看不到有人在javascript中更大程度地使用它们。这不是一个好习惯,还是我们在javascript中不需要它们?
Answers:
人们应该避免使用throw
错误作为在应用程序中传递错误条件的方法。
该throw
语句仅应使用“因为这绝不会发生,崩溃和燃烧。请勿以任何方式优雅地恢复”
try catch
但是,在主机对象或ECMAScript可能引发错误的情况下使用。
例:
var json
try {
json = JSON.parse(input)
} catch (e) {
// invalid json input, set to null
json = null
}
在node.js社区中,建议您在回调中传递错误(因为错误仅发生在异步操作中)作为第一个参数
fs.readFile(uri, function (err, fileData) {
if (err) {
// handle
// A. give the error to someone else
return callback(err)
// B. recover logic
return recoverElegantly(err)
// C. Crash and burn
throw err
}
// success case, handle nicely
})
还有其他问题,例如try / catch确实很昂贵,而且很丑陋,根本无法与异步操作一起使用。
因此,由于同步操作不应引发错误,并且不适用于异步操作,因此除了主机对象或ECMAScript引发的错误外,没有人使用try catch
Error
,但它们之间相差无几。
document.getElementById
,当元素不存在时不抛出,而仅返回null
。几乎所有情况都可以这样做
由于Javascript具有异步特性,因此在Java语言中进行尝试/捕获并不像在其他语言中那样防弹。请考虑以下代码段:
try {
setTimeout(function() {
do_something_that_throws();
}, 1000);
}
catch (e) {
alert("You won't see this!");
}
问题在于控制流try
在do_something_that_throws()
执行之前就离开了该块,因此永远不会捕获在回调中引发的错误。
因此,在许多情况下,try / catch基本上是不合适的,而且是否有人异步执行代码并不总是很明显。幸运的是,javascript带有其独特的单线程异步回调习惯用法以及对实际闭包的支持,提供了一种绝妙的选择:连续传递样式错误处理。只需将对任何错误的正确响应作为函数传递,例如:
setTimeout(function () {
do_something_that_calls_err(function(err) {
alert("Something went wrong, namely this: " + err);
}),
1000);
这些答案很多都有些陈旧,没有考虑到新的ES7功能async
和await
。
使用async
/,await
您现在可以按需要获取异步控制流:
async function email(address) {
try {
// Do something asynchronous that may throw...
await sendEmail({ to: address, from: 'noreply@domain.com`, subject: 'Hello' })
} catch(err) {
if (err instanceof SomeCustomError) {
elegantlyHandleError(err)
} else {
throw err
}
}
})
了解更多关于async
/ await
这里。您可以使用async
/ await
现在使用babel。
javascript中的try-catch与实现它们的任何其他语言一样有效和有用。主要原因之一是,它在javascript中的使用率不如其他语言。这与javascript被视为丑陋的脚本语言的原因相同,与人们认为javascript程序员不是真正的程序员的原因相同:
如此之多的人(由于浏览器唯一支持的语言)才暴露了javascript的事实,这意味着您那里有很多非专业的代码。当然,还有许多次要原因:
catch
无法执行(异步操作)无论如何,都应该使用try-catch ,但是您当然应该学习如何正确使用它们 -像编程中的所有其他内容一样。
我认为,try..catch
JavaScript中罕见的大部分原因是因为该语言对错误的容忍度很高。绝大多数情况可以通过使用代码检查,良好的默认设置和异步事件来处理。在某些情况下,仅使用模式即可防止出现问题:
function Foo() {
//this may or may not be called as a constructor!!
//could accidentally overwrite properties on window
}
function Bar() {
if (!(this instanceof Bar)) {
return new Bar();
}
//this will only work on Bar objects, and wont impact window
}
JS中不存在其他语言中导致异常发生的一些主要问题。绝大多数时间不需要类型转换。相反,首选方法通常是进行功能检查(强制使用特定的接口):
function doFoo(arg) {
if (arg.foo) {
arg.foo();
} else {
Bar.prototype.foo.call(arg);
}
}
随着async
/ await
语言的加入,try..catch
它变得越来越普遍。承诺是的异步形式try..catch
,应该期望:
doSomething().then(
doSomethingWithResult,
doSomethingWithError
)
改为:
try {
const result = await doSomething()
doSomethingWithResult(result)
} catch (e) {
doSomethingWithError(e)
}
可能在Javascript中未大量使用try / catch的另一个原因是该结构在Javascript的第一个版本中不可用...它是在以后添加的。
结果,某些较旧的浏览器不支持它。(实际上,这可能会在某些较旧的浏览器中引起解析器/语法错误,这比大多数其他类型的错误更难“防御性编程”。)
更重要的是,由于最初不可用,因此最初发布的Java脚本内置函数(在许多语言中称为“库”函数)不会使用它。(如果它不是“抛出”,而是在遇到问题时只返回“ null”,那么从someobject.somefunction()中“捕获”错误就不太好。)
另一个可能的原因是,try / catch机制一开始似乎并没有必要(而且似乎并没有那么有用)。仅当调用通常嵌套在多个级别时才真正需要它。仅返回某种ERRNO即可用于直接调用(尽管要使其在可用时真正有用,但大多数语言的最佳实践是在各处使用它,而不仅仅是深度嵌套的调用)。由于最初希望Javascript逻辑小而简单(毕竟,它只是网页的附件:-),所以不希望将函数调用深度嵌套,因此似乎没有必要使用try / catch机制。
我相信它们使用的并不多,因为在Javascript客户端代码中抛出异常会使调试页面更加困难。
我通常不希望抛出异常,而宁愿显示警报框(即alert("Error, invalid...");
)
听起来可能很奇怪,但是如果客户正在使用您构建的页面而该页面引发异常,则Javascript错误会在客户端发生,除非该客户是精通技术的编码器,否则他将永远无法分辨你是什么问题。
他只会打电话给您说:“嘿,第X页不起作用!”,然后由您自己找出问题所在以及代码中的位置。
通过使用警报框,他更可能打来电话并说:“嘿,当我单击X页面的按钮A时,它显示一个框显示...”,相信我,这将很容易找到错误。
While in java or *any other language* it is mandatory to have error handling...
- 并不是的。Java,是的,但是有很多语言不坚持尝试捕获(例如C#)。