はじめに
今まで私は主にelseを使用してコードを書いてきましたが、より簡潔にコードを作成するための方法を探したところとある記事を発見し、役に立ったので紹介したいと思います。
elseを使わない作成例
例えば以下のコードを見ると、何を意味しているのかすぐに分かります。
if (x !== 0) {
return 10 / x;
} else {
return 0;
}
下のコードではどうでしょうか。
else {
return 0;
}
なぜ0をリターンするのか、一般的な返却形態なのか、 問題があるから返すのか、
すぐに理解しづらいです。
このような時は、さまざまな状況である変数の値を検証する必要がある場合が多いです。
const doSomething = (err, something) => {
if (err) {
console.log(err);
} else {
if(something.OK) {
//Do Something
} else {
console.log('Not Invalid');
}
}
}
if
とelse
が入り混じっています。以下のように変更してみましょう。
const doSomething = (err, something) => {
if (err) {
return console.log(err);
}
if (!something.OK) {
return console.log('Not Invalid');
}
//Do Something
}
このように重要なロジックが動作する前に検査を行い、
それに応じてリターンすることで、コードをより明確に記述できます。
非同期の処理の場合
非同期処理の場合、次のように書くことができます。
const doSomething = async (err) => {
if (err) {
throw err;
}
//Do something
}
throw
を適切に活用して検証を迅速に行い、関数を中断させることができます。
Expressの場合
多くの人々が次のような問題を見落としています。
app.get('/', (req, res, next) => {
res.send({});
console.log('hi'); // hi
});
res.send
メソッドは return
や throw
のようにコードを中止させません。
つまり、console.log
関数はそのまま実行されます。
以下のコードはexpressで推奨されるエラー処理handler
です。
app.use((err, req, res, next) => {
// Error handler
// エラー処理ロジック...
});
このhandler
は、next
メソッドのパラメータが空でない場合に機能します。
つまり、以下のようにhandler
内でnext
メソッドのエラーを取り込み、
err
パラメータを介してエラーを受け取り処理できます。
app.get('/', (req, res, next) => {
next(new Error('Error'));
});
しかし、上記で言及した方法では、
next
関数はreturn
やthrow
と同様に関数を即座に中断させないため、
次のように使用する必要があります。
app.get('/', (req, res, next) => {
return next(new Error('Error'));
});
Expressの使用例
APIの利用者がデータを検証し、
エラーが発生した場合は即座にエラー処理handler
に投げます。
app.post('/auth', (req, res, next) => {
// from FE
const inputId = req.body.id;
if (!inputId) {
return next({ status: 400, message: 'Bad Request' });
}
// Do Something
});
このようにしてコードが簡潔になりました。
まとめ
Else文を使うと、エラーハンドリングとハッピーパスのために同じインデントレベルを強制するので、
どんなコードでも可読性が損なわれます。またコードに影響を与えるロジックから分離してしまいます。
しかし早期リターンとロジックをヘルパー関数に分割するという2つのテクニックを使うことで解決できるので、Else文を使わない方が良いといえます。
参考