【javaScript基礎】異常処理


異常を理解することはjavaScriptで対象に向けてプログラミングすることが非常に重要であり、異常は非常に強力な処理エラーの方式である.
エラー処理
         まず問題のあるコードを見ます.
nonexistant();
上記の例では、存在しない変数にアクセスした場合、プログラムはどのように処理されますか?昔の処理はプログラムが直接崩壊して死んでしまうので、このような処理は我慢できません.
    一番簡単な処理方法は先に検査します.このように:
	if (window.func) {
  		func();
	}
         上記のような処理はまだエラーが発生する可能性があります.window.funcは関数ではないかもしれないので、まだこのような検査が必要です.
if (typeof(func) == 'function') { 
    func();
}
上記の例では、typeofは変数の存在を確保し、関数であることを確認します.
         私たちは希望を持って、多くの必要な検査をして、funcを実行することが安全であることを確認しました.しかし、もしfuncの関数が体内にエラーがあったら?私たちがもっとやりたいのは、プログラムを死なせることではなく、エラーを処理することです.
         私たちはtrycatch構造で処理できます.
Try catch構造
         try...catchを使って、私達がよく使うif文の構造の代わりにエラーを処理します.私達は下記のコードで上記の例を書き換えます.
	try {
	  func() 
	} catch(e) {
	  alert(e)
	}
         tryブロックにエラーが発生した場合、catchブロックが機能し、パラメータeは異常発生時の一部の情報を含む特別な異常対象として付与される.
         変数eはErrerオブジェクトの一例(またはTypeErr,ReferenceErrorなどから継承)です.
         このエラーの属性はブラウザによって少し違っています.詳細はErrr in MDNを参照してください. 和 Errr inMSDN
基本属性は同じです.
name:エラータイプは、ブラウザによって生成されたerrorに対して、TypeErrのような構造関数と一致します. ReferenceErrer など
メッセージ:より詳細なerror情報を教えてください.
以下の例では、tryブロックに他の宣言を追加し、nameとmessageがプリントされます.
	try {
	  var a = 5
	  var res = func(a) 
	  if (res > 0) doA()
	  else doB()
	 
	} catch(e) {
	  alert("name:" + e.name + "
message:" + e.message) }
多くの異常はtry.catchに捕獲されます.tryによって可能なエラーを検出すればいいです.
スタックの情報を取得
         Firefox、Chrome、Operaブラウザはstack属性を提供しています.stack属性を通して、異常を引き起こすすべての入れ子の呼び出し情報を見ることができます.例は以下の通りです.
	function f(a) { 
	  g(a+1) 
	}
	 
	function g(a) {
	  notexists;
	}
	try { f(1) } catch(e) { alert(e.stack)
         残念なことに、IEにはこの属性がなく、IE 9にもない.
Try...catch...finally完全形
         完全な構成形態は3つの部分から構成されています.
	try {
	   .. try statemenets ..
	} catch(exception) {
	   .. catch statements ..
	} finally {
	   .. finally statements ..
実行過程は以下の通りです.
1. Try中の声明は実行されます.もしエラーが発生しないなら、catchの部分は無視されます.
2. エラーが発生すれば、exception変数はエラーオブジェクトに割り当てられ、catchの声明も実行されます.
3. 以上の2つの場合、tryまたはcatchで実行されていなくてもfinallyコードは実行されます.
try...catch...finally...return
以下の例では、tryにreturn文があり、かつfinallyブロックがある場合、finallyの実行が完了したら、return文が実行される.
    function inc(a) {
	 
	  try {
	    return a+1
	  } catch(e) {
	    // ..
	  } finally {
	    alert('done')
	  }
	}
	 
	alert( inc(1) )
//    :‘done’, 2
Throw声明
すべてのエラーは2つに分けることができます.
1. プログラム設計エラー:入力ミスなどの開発者によるものが多いです.
2. 異常フローエラー:このエラーはプログラム実行中の正常部分です.共通のエラーはフォーム認証です.ユーザーがいくつかのエラーを入力した場合、通常のやり方はこのエラーを処理し、ユーザーに繰り返し入力させることです.
         try...catchで異常エラーを処理するには、throw手動でエラーを出す必要があります.
         文法は:throw e、eは何でもいいです.何を投げても、キャッチャーに捕まることができますが、tryブロックの外に投げたら、プログラムが崩壊する可能性があります.
         次の例では、throwがどのように働いているかを示しています.
	  
	try {
	  throw 5
	} catch(e) {
	  alert("Caught: "+e)
	}
フォーム検証例
         例えば、年齢を検証して、合法かどうかチェックします.
function validateAge(age) { // age is a text to check 
    if (age === '') return; // no age is valid
    age = +age
    if (isNaN(age)) {
        throw { name: 'BadAge', message: 'Invalid age' }
    }
    if (age < 5 || age > 150) {
        throw { name: 'BadAge', message: 'Age out of range' }
    }
}

try {
    var age = prompt("Enter your age please?") 
    validateAge(age)
    alert("The age is accepted!")
} catch(e) {
    alert("Error: "+e.message)
}
通常、投げられた例外オブジェクトは、Errオブジェクトから継承されることが望ましい.このようにして、errorを管理するより良い方法を提供する.
変化を検証する
現在、検証条件を追加する必要がある場合、ユーザから提供された値を検証することは、必ず提供され、有効な年齢である.例えば、私たちはvalidateAgeとvalidateRequiredを実現しました.
エラーの検出方法
var value = input.value

    // VALIDATE

    var error = validateRequired(value)

    if (!error) {
        error = validateAge(value)
    }

    if (!error) { 
        /* another validator... */
    }
    // FINISHED VALIDATING
    if (error) {
        /* process error */
    } else {
        /* success */
}
Try…catch方法
このような方法は、エラーを検出したら手動で投げ出すことです.
    var value = input.value
	try {
	  validateRequired(value)
	  validateAge(value)
	  // other validators in a row
	 
	  /* success */
	} catch(e) {
	  /* process error */
	}
私たちはいちいち検査する必要はありません.エラーが発生する可能性のある検証をtryブロックに入れればいいです.もし間違いがあると、catchの中で捕獲されます.間違いがないなら、自然にスムーズに実行します.catchブロックに入ることはありません.
比較
try.catchでエラーを処理するにはいくつかの利点と欠点があります.
1. Try…catch方法はエラーを処理するとより清潔で、簡単に依存し、すべてのエラーを捕獲することができます.
2. 検出できない異常がある可能性があります.try...catchは唯一解決できる方法です.ブラウザのいくつかの特性を検出します.
3. Try…catch構造はコードの位置を何行か占めています.コードが優雅ではないように見えます.
異常分析と再投げ出し
         コードによっては違ったエラーが発生する場合があります.この場合は常にifで正しい処理を選択します.以下は偽コードです.
try {
	  // 1. do smth
	} catch(e) {
	  if (e instanceof ValidationError) {
	    // 2.1 process e
	  } else if (e instanceof PermissionError) {
	    // 2.2 process e
	  } else {
	    // 3. we don't know how to deal with e
	    throw e
	  }
	}
1. tryブロックのコードは複雑です.異常を出すかもしれません.Validation Errなど、いくつかの異常があります.
2. catchブロックでは異常を解析して処理します.
3. さもないと、異常はもう一度投げ直します.外にもう一つの階があると仮定します.
異常はもう一度投げ出されるか、処理されるか、あなたが何をしているかを完全に知っていない限り、放置してはいけません.
	try {
	  func()
	} catch(e) {
	  if (e instanceof KnownError) {
	    // ...
	  } 
	}
上記のコードセグメントでは、KnownErr異常以外に、他の異常は無視されました.
正直に言うと、javaの世界にはこのような異常を処理しない場合がありますが、処理しない異常がいつも隠れています.
         想像してみると、funcの中にコードが入力されていないとデバッグが難しくなります.TypeErrorのせいです. とReferenceErrer 異常は無視された.
締め括りをつける
1. Try...catch...finally構造は、tryブロックにいくつかの声明を入れることができます.それぞれのcatchブロックで異常処理ができます.
2.  すべてのエラーを処理することができます.JSが自分で作ったものと手動で投げ出したものを含みます.
3.  厳密にはjavaScriptはthrowの任意の値を許容していますが、すべてのエラーがErrオブジェクトを継承し、継承レベルを形成することを推奨します.この場合、instance of 仕事がとても上手です.例えば、すべてのe instance of ValidationErrの異常を捉えることができます.Validation Errorは、AgeValidation Errorを含みます. RequiredValidation Error など.