JavaScript 反静默技术来指示失败
当错误确实发生并且函数无法继续执行时,在 JavaScript 中报告错误而不是依赖 null 和 undefined 是一个好方法。我可以想到三种方法:
- 不执行任何
- 操作抛出异常
- 断言
这是一个简单的示例场景 - 一个将传入金额记入用户帐户的函数。函数 credit
是 Account 的一部分对象。
这是天真的解决方案。
function credit(amount) {
this.balance += amount;
}
这种方法的一个主要问题是无效数据。让我们修复它,并使用返回值来指示操作失败。
function credit(amount) {
if(!isInt(amount)) {
return false;
}
this.balance += amount;
}
这是对前一个的改进,但客户端代码必须检查返回值以确保操作成功。为系统中的基本上每个方法执行此操作可能会变得很麻烦。
if(!johnDoe.credit(100)) {
// do some error handling here
}
第三种方法与第二种方法类似,是抛出异常。由于我们自己抛出异常,因此可能会抛出特定类型的异常,而不是一般类型的异常。
function credit(amount) {
if(!isInt(amount)) {
throw new InvalidAmountError(amount);
}
this.balance += amount;
}
与引发异常类似的第四种方法是在代码中使用断言。与上述方法相比,一个缺点是,由于断言是通用的,我们失去了抛出自定义异常的能力。不过,通过在每个断言调用中传递要抛出的对象仍然是可能的。
function credit(amount) {
assert(!isInt(amount), "Amount to credit is not an integer");
this.balance += amount;
}
全局 assert
函数很容易编写,并且使代码更短一些。
function assert(value, message) {
if(value !== true) {
throw new AssertionError(message);
}
}
function AssertionError(message) {
this.message = message;
}
AssertionError.prototype.toString = function() {
return 'AssertionError: ' + this.message;
}
在这些方法中,什么是处理意外值和不愉快路径的好方法。这里没有提到的还有其他有用的方法吗?
What would be a good way to report errors in JavaScript instead of relying on nulls, and undefineds when errors do occur and a function is unable to proceed forward. I can think of three approaches:
- do nothing
- throw an exception
- assert
Here's a simple example scenario - a function that credits a user account with the amount passed in. The function credit
is part of an Account
object.
Here's the naive solution.
function credit(amount) {
this.balance += amount;
}
A major problem with this approach is invalid data. Let's fix it up, and use a return value to indicate that the operation failed.
function credit(amount) {
if(!isInt(amount)) {
return false;
}
this.balance += amount;
}
This is an improvement over the previous one, but client code will have to check the return value to ensure that the operation succeeded. Doing this for basically every method in the system can become cumbersome.
if(!johnDoe.credit(100)) {
// do some error handling here
}
A third approach, similar to the second one, is to throw an exception. Since we are throwing the exception ourselves, could throw a specific type of exception rather than a general one.
function credit(amount) {
if(!isInt(amount)) {
throw new InvalidAmountError(amount);
}
this.balance += amount;
}
A fourth approach similar to throwing exceptions is to use assertions in your code. One shortcoming compared to the above approach is that since the assert is generic, we lose the ability to throw custom exceptions. It is still possible though by passing the object to throw in each assert call.
function credit(amount) {
assert(!isInt(amount), "Amount to credit is not an integer");
this.balance += amount;
}
A global assert
function is easy to write and makes the code a little shorter.
function assert(value, message) {
if(value !== true) {
throw new AssertionError(message);
}
}
function AssertionError(message) {
this.message = message;
}
AssertionError.prototype.toString = function() {
return 'AssertionError: ' + this.message;
}
Out of these approaches, what would be a good way to deal with unexpected values, and unhappy paths. Are there any other approaches not mentioned here that could be useful?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
考虑使用客户端日志框架来报告错误,例如 Log4js。人们可以在浏览器中记录消息(即信息、调试、警告、错误),或者通过 Ajax 将消息保存到服务器,具体取决于应用程序。
Log4js 网站还提供了其他 JavaScript 日志框架列表。
使用自定义异常示例的一个好方法是抛出异常并根据您认为合适的方式记录错误。
Consider a client-side logging framework to report errors, such as Log4js. One can log messages (i.e., info, debug, warn, error) in the browser or persist messages to the server via Ajax, depending on the application.
The Log4js site also provides a list of other JavaScript logging frameworks.
A good approach, using your custom exception example, would be to throw the exception and log the error as you see fit.
不一定:
构造函数是函数。函数是一流的值。请随意传递它们。
Not necessarily:
Constructors are functions. Functions are first class values. Feel free to pass 'em around.