質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

例外処理

例外処理(Exception handling)とは、プログラム実行中に異常が発生した場合、通常フローから外れ、例外として別の処理を行うようにデザインされたプログラミング言語構造です。

Q&A

4回答

5980閲覧

javascriptの例外処理について

lmnwtr2027

総合スコア11

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

例外処理

例外処理(Exception handling)とは、プログラム実行中に異常が発生した場合、通常フローから外れ、例外として別の処理を行うようにデザインされたプログラミング言語構造です。

0グッド

1クリップ

投稿2016/02/15 12:50

###前提・実現したいこと
javascriptでリファクタリングした際、例外処理の取り扱いがよくわからなかったので教えて下さい。

###ソースコード
以下のように、ボタンを押すとエラーチェックを行い、問題ない場合のみ次の処理を行う処理を書きました。
この時、エラーチェック処理がとても長いため、この部分を関数に切り出そうとしました。

$(".sample").click(function(){ var isError = true; /* 長いエラーチェック。エラーの場合、isError=falseをセット。 */ if ( isError = false ){ alert("Error発生"); return false; } /* 上のエラーチェックにひっかかない場合のみ行う処理をここに記述 */ })

すると、try~catchでくくる必要があり、余計にソースが分かり辛くなったように感じました。

$(".sample").click(function(){ try{ validate(); } catch(e){ return false; } /* 上のチェックにひっかかない場合に行う処理をここに記述 */ }) function validate(){ var isError = true; /* 長いエラーチェック。エラーの場合、isError=falseをセット。 */ if ( isError = false ){ alert("エラー発生"); throw "Error" } }

こういう場合、もっと良い方法はないのでしょうか。
また、これでよい場合throw節には普通何を投げればよいのでしょうか。
曖昧な質問ですみませんが、よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

提示されているコードだと、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() が超複雑で、さらに細かい検証関数を呼び出すような作りにした場合でも、その中で例外を投げるだけで簡単に大域脱出できるということです。

投稿2016/02/15 14:22

unau

総合スコア2468

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

=の比較演算子は=2つまたは3つです。
===の厳密な比較の方でいいと思います。

javascript

1/* 誤 */ 2if(isError = false) 3 4/* 正 */ 5if(isError == false) 6 7if(isError === false)

また、他の方も仰っていますが、初期値をfalseにして、
エラーがあったらtrueにした方が、このように書けます。

javascript

1var isError = false; 2 3// エラーがあったら 4isError = true; 5 6if(isError){ //エラー処理 }

投稿2016/02/16 01:07

yamato_hikawa

総合スコア2092

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

throw は処理を強制的に停止させたい場合に使いますが、せっかく throw したところを try-catch で例外を止めて処理させる部分に矛盾を感じます。
例外を発生させたいのなら throw new Error で強制終了させれば良いですし、静かにエラーを発生させたい(強制終了したくない)のなら throw を使わないようにしてみてはいかがでしょうか。

JavaScript

1'use strict'; 2function validate (element) { 3 element.checkValidity(); 4 5 var validity = element.validity, 6 error = []; 7 8 if (element.valueMissing) { 9 error.push('required'); 10 } 11 12 if (element.patternMismatch) { 13 error.push('pattern'); 14 } 15 16 return error; 17} 18 19function handleClick (event) { 20 var error = validate(event.currentTarget.elements['hoge']), 21 errorMsg {required: '必須項目です', pattern: '文法エラーです'}; 22 23 for (var i = 0, l = error.length; i < l; ++i) { 24 console.error(errorMsg[error[i]]); 25 } 26} 27jQuery(('.sample').on('click', handleClick);

Re: lmnwtr2027 さん

投稿2016/02/15 16:01

think49

総合スコア18162

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

validate でスローせずに boolean を返してみてはどうですか?
ちなみに、isError という名前にする場合は true がエラーです。
false をエラーとしたいのであれば、変数名は isValid などにすべきですね。

javascript

1$(".sample").click(function(){ 2 if (validate()){ 3 alert("Error発生"); 4 return false; 5 } 6 /* 上のチェックにひっかからない場合に行う処理をここに記述 */ 7}) 8 9function validate(){ 10 var isError = false; 11 /* 12 * 長いエラーチェック。エラーの場合、isError = trueをセット。 13 */ 14 return isError; 15}

投稿2016/02/15 13:12

root_jp

総合スコア4666

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問