提示されているコードだと、try/catch の「大域脱出」の利点を享受できるものになっていませんね。通常の関数呼び出しのフローより大きく脱出できるところが嬉しいわけで、だからこそ異常系の処理に向くわけです(が、異常系処理以外でも使いどころはあります)。
javascript
1$(".sample").click(function(){
2 try{
3 validate();
4 }
5 catch(e){ // ※ 例外捕捉
6 return false;
7 }
8 /* 上のチェックにひっかかない場合に行う処理をここに記述 */
9})
10
11function validate(){
12 ...
13 if (/* あれのチェック */) throw new Error('あれがおかしい');
14 ...
15 if (/* これのチェック */) throw new Error('これがおかしい');
16 ...
17 if (/* それのチェック */) throw new Error('それがおかしい');
18 return; // 問題ナッシング
19}
ここで validate()
が別関数になっているところは重要ではありません。異常を発見したらボンボン例外を投げちゃうことで、正常系の処理を書くことに集中できます。下のコードのほうが本質を理解しやすいかもしれません。
javascript
1$(".sample").click(function() {
2 try{
3 doSomething();
4 }
5 catch(e){ // ※ 例外捕捉
6 return false;
7 }
8});
9
10function doSomething() {
11 ...
12 if (/* あれのチェック */) throw new Error('あれがおかしい');
13 ...
14 if (/* これのチェック */) throw new Error('これがおかしい');
15 ...
16 if (/* それのチェック */) throw new Error('それがおかしい');
17 /* 上のチェックにひっかかない場合に行う処理をここに記述 */
18}
validate()
や doSomething()
の中で例外を投げ分けることで、※印のところで例外の種類による処理の変更なんかもできます。
余談ですが、手続き型言語の多くに提供されている return
も、いわゆる構造化プログラミングのフローを飛び越えて脱出できる命令と考えることができます。
javascript
1$(".sample").click(function() {
2 if (! validate()) return false;
3 /* 上のチェックにひっかかない場合に行う処理をここに記述 */
4});
5
6function validate() {
7 ...
8 if (/* あれのチェック */) return false;
9 ...
10 if (/* これのチェック */) return false;
11 ...
12 if (/* それのチェック */) return false;
13 return true; // 問題ナッシング
14}
最初のコードとほぼ同じです。違うところは、return
は自分のいる関数から脱出することしかできないのに対し、throw では try をしかけたところまで脱出できることです。つまり、validate()
が超複雑で、さらに細かい検証関数を呼び出すような作りにした場合でも、その中で例外を投げるだけで簡単に大域脱出できるということです。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。