nullに依存する代わりに、JavaScriptでエラーを報告するための良い方法は何でしょうか。エラーが発生し、関数が先に進むことができない場合は未定義です。私は3つのアプローチを考えることができます:
- 何もしない
- 例外をスローする
- 主張する
簡単なシナリオ例を次に示します。渡された金額をユーザーアカウントにクレジットする関数です。この関数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
}
2番目のアプローチと同様の3番目のアプローチは、例外をスローすることです。自分で例外をスローしているので、一般的な例外ではなく、特定のタイプの例外をスローする可能性があります。
function credit(amount) {
if(!isInt(amount)) {
throw new InvalidAmountError(amount);
}
this.balance += amount;
}
例外のスローに似た4番目のアプローチは、コードでアサーションを使用することです。上記のアプローチと比較した場合の1つの欠点は、アサーションが汎用であるため、カスタム例外をスローする機能が失われることです。ただし、オブジェクトを渡して各assert呼び出しをスローすることにより、それは可能です。
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;
}
これらのアプローチのうち、予期しない値や不幸な道に対処するための良い方法は何でしょうか。ここで言及されていない、役立つ可能性のある他のアプローチはありますか?