はじめに
おそらく基本的なポイントですが、if文においてはelseを避けた方が長くなれど可読性は上がると思い整理しておきます。
LeetCodeの第三問「To Be Or Not To Be」より。
問題
Write a function expect that helps developers test their code. It should take in any value val and return an object with the following two functions.
- toBe(val) accepts another value and returns true if the two values === each other. If they are not equal, it should throw an error "Not Equal".
- notToBe(val) accepts another value and returns true if the two values !== each other. If they are equal, it should throw an error "Equal".
解答例
一番最初に思いついたのが、elseを使った以下の解答です。
/**
* @param {string} val
* @return {Object}
*/
var expect = function(val) {
return {
toBe: function(val2) {
if (val === val2) {
return true;
} else {
throw "Not Equal";
}
},
notToBe: function(val2) {
if (val !== val2) {
return true;
} else {
throw "Equal";
}
}
}
};
/**
* expect(5).toBe(5); // true
* expect(5).notToBe(5); // throws "Equal"
*/
しかし「バイト先のソースコードでelseなんて見たことないぞ?」と思い返し、次のように書き直してみました。
if...elseを使わず、ifのみで書く
/**
* @param {string} val
* @return {Object}
*/
var expect = function(val) {
return {
toBe: function(val2) {
if (val === val2) {
return true;
}
if (val !== val2) {
throw "Not Equal";
}
},
notToBe: function(val2) {
if (val !== val2) {
return true;
}
if (val === val2) {
throw "Equal";
}
}
}
};
/**
* expect(5).toBe(5); // true
* expect(5).notToBe(5); // throws "Equal"
*/
上がelseなしで書き直したソースコードです。
2行ほど増えましたが、条件が明瞭になった気がします。
早期リターン
chatGPTに見てもらったところ、早期リターンという考え方があるそうです。
/**
* @param {string} val
* @return {Object}
*/
var expect = function(val) {
return {
toBe: function(val2) {
if (val === val2) {
return true;
}
throw "Not Equal";
},
notToBe: function(val2) {
if (val !== val2) {
return true;
}
throw "Equal";
}
}
};
/**
* expect(5).toBe(5); // true
* expect(5).notToBe(5); // throws "Equal"
*/
見たまんまですが、これだとわざわざエラーをスローする条件を書く必要がありません。
(個人的にはさっきのifのみで書く方が条件は分かりやすいですが好みの問題でしょうか)
if文を一行にまとめる
さらにif文のブロックを省略して、一行にまとめることもできます。
/**
* @param {string} val
* @return {Object}
*/
var expect = function(val) {
return {
toBe: function(val2) {
if (val === val2) return true;
throw "Not Equal";
},
notToBe: function(val2) {
if (val !== val2) return true;
throw "Equal";
}
}
};
/**
* expect(5).toBe(5); // true
* expect(5).notToBe(5); // throws "Equal"
*/
ただこの書き方は、職場のプルリクのレビューで「ブロックは省略せずお願いします」と指摘されている箇所を見たことがあります。
コーディング規約上で許されている場合は使用していきたいですね!
まとめ
elseはネストが深くなることにより可読性に欠けます。
なので極力避けてif文を書きたいと思います。