`throw new Error`と` throw someObject`の違いは何ですか?


378

コードのインスタンスでわざとスローされたカスタムエラーをキャッチする一般的なエラーハンドラーを作成したいと思います。

throw new Error('sample')次のコードで気に入ったとき

try {
    throw new Error({'hehe':'haha'});
    // throw new Error('hehe');
} catch(e) {
    alert(e);
    console.log(e);
}

ログがFirefoxに表示されError: [object Object]、オブジェクトを解析できませんでした。

2番目throwのログは次のように表示されます。Error: hehe

私がしたとき

try {
    throw ({'hehe':'haha'});
} catch(e) {
    alert(e);
    console.log(e);
}

コンソールは次のように表示されました:Object { hehe="haha"}エラープロパティにアクセスできました。

違いはなんですか?

コードに見られる違いはありますか?同様に文字列は文字列として渡され、オブジェクトはオブジェクトとして渡されますが、構文は異なりますか?

エラーオブジェクトのスローについては調べていません...文字列のスローのみを実行していました。

上記の2つの方法以外に方法はありますか?


6
throw new Error({prop:val})の問題は、それがErrorの有効な構成ではないことです。Hemantによって議論されたように、エラーには既知の特性があります。
grantwparks 2013年

回答:


216

ここにエラーオブジェクトとあなた自身のエラーを投げることについて良い説明があります

エラーオブジェクト

エラーが発生した場合、そこから何を抽出できますか?すべてのブラウザのErrorオブジェクトは、次の2つのプロパティをサポートしています。

  • name:エラーの名前。具体的には、エラーが属するコンストラクター関数の名前。

  • メッセージ:エラーの説明。この説明はブラウザーによって異なります。

nameプロパティにより、6つの可能な値が返されます。これは、前述のように、エラーのコンストラクターの名前に対応しています。彼らです:

Error Name          Description

EvalError           An error in the eval() function has occurred.

RangeError          Out of range number value has occurred.

ReferenceError      An illegal reference has occurred.

SyntaxError         A syntax error within code inside the eval() function has occurred.
                    All other syntax errors are not caught by try/catch/finally, and will
                    trigger the default browser error message associated with the error. 
                    To catch actual syntax errors, you may use the onerror event.

TypeError           An error in the expected variable type has occurred.

URIError            An error when encoding or decoding the URI has occurred 
                   (ie: when calling encodeURI()).

独自のエラーをスローする(例外)

制御がtryブロックからcatchブロックに自動的に転送される前に、6種類のエラーのいずれかが発生するのを待つ代わりに、独自の例外を明示的にスローして、強制的にオンデマンドで発生させることもできます。これは、エラーが何であるか、そして制御をいつキャッチに移すべきかについて独自の定義を作成するのに最適です。


4
そうそう。これは、この質問をする前に見逃していた良い点の1つです。とにかく、これに関連する情報を検索しているユーザーはクリアされます。今、私は何が何であるかを明確にしています。:) ありがとうございました。数日後に投票に戻ります。
Jayapal Chandran

185
まだ質問に答えていませんが、最も投票された答えですか?
user9993 2017年

@ user9993ユーザーから寄せられた質問は、当時のチャットごとに詳細な理解を求めていたため、ユーザーに役立つ回答が提供されています。それが賛成票と賛成票の理由です。
Hemantメタリア

5
@HemantMetaliaしかし、彼が正しい、答えは述べられているようにOPsの質問に答えようとしてもほんの少しの試みでさえ示していません。チャットに残るはずの非常に異なるチャットの回答が回答された場合、ここでの質問と回答には論理的なつながりがまったくありません。
Mörre

そして、元の質問に答えるには、JavaScriptには関係ありません。ただし、Error慣例として(およびサブクラス)が使用されます。また、デフォルトでスタックプロパティを提供しますが、手動で他のプロパティに追加することもできます。ですから、それはほとんどが慣習であり、プログラムの流れは投げたものの影響を受けませんthrow。あなたは可能性がありthrow "grandmother down the stairs";、それが機能し、記者、デバッガが期待ハンドリング付属スタックトレースとエラーがないことを除いて、同じように機能するであろうError、より正確に、または付属していますプロパティを。
Mörre

104

「私は悪だ」を投げる

throwエラーをキャッチすると、以降の実行を終了し、メッセージ文字列を公開 します。

try {
  throw "I'm Evil"
  console.log("You'll never reach to me", 123465)
} catch (e) {
  console.log(e); //I'm Evil
}

スロー後のコンソールが終了の原因に到達することはありません。


新しいエラーをスローする(「私はとても甘い」)

throw new Error2つのパラメータメッセージを含むエラーイベントを公開します。さらに実行を終了します

try {
  throw new Error("I'm Evil")
  console.log("You'll never reach to me", 123465)
} catch (e) {
  console.log(e.name, e.message); //Error, I'm Evil
}


16
「throw Error( 'whatever')」と「throw new Error( 'whatever')」の違いについてはどうですか-どちらも機能します。
joedotnot

9
エラーは機能し、新しいエラーはコンストラクタです。両方の作品と同じ developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
Nishchit Dhanani

5
@NishchitDhananiそのような判読不能で間違ったコメントが賛成票を獲得するのは奇妙だと思います。「エラーは機能的」でも「新しいエラーはコンストラクター」でもまったく意味がなく、間違っています。そのコンテキストでは、リンクが「証明」するものと正確に何が想定されているかは不明です。これはのMDNページErrorです。コメントへの接続はどこにありますか?OPの質問にコメントし、回答する人々の半分は、黙っているべきでした。
Mörre

Mörre参照してください。この節@ Used as a functionこのリンクから... developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
Nishchit Dhanani

わかった。それは機能です。
Nishchit Dhanani

73

次の記事では、どちらがより良い選択であるかについて、さらに詳しく説明します。throw 'An error'またはthrow new Error('An error')

http://www.nczonline.net/blog/2009/03/10/the-art-of-throwing-javascript-errors-part-2/

new Error()前者を使用する場合、Internet ExplorerやSafari(バージョンが不明)などのブラウザはメッセージを正しく報告しないため、後者()の方が信頼性が高いことが示唆されています。

これを行うとエラーがスローされますが、すべてのブラウザーが期待どおりに応答するわけではありません。Firefox、Opera、Chromeはそれぞれ「キャッチされない例外」メッセージを表示し、メッセージ文字列を含めます。SafariとInternet Explorerは単に「キャッチされない例外」エラーをスローし、メッセージ文字列をまったく提供しません。明らかに、これはデバッグの観点からは最適ではありません。


36

あなたは最初にこのコードに言及します:

throw new Error('sample')

そしてあなたの最初の例ではあなたは書く:

throw new Error({'hehe':'haha'}) 

最初のErrorオブジェクトは、文字列値(この場合は「sample」)を想定しているため、実際に機能します。2つ目は、オブジェクトを渡そうとしているためではなく、文字列を期待しています。

エラーオブジェクトには「message」プロパティがあり、これは「sample」になります。


12
2番目のものは機能しますが、あまり便利な方法ではありません。toString()渡されたオブジェクトに対してメソッドを実行するため[object Object]、エラーが発生します(Opの記述)。
2018年


15

throwオブジェクトとしてできます

throw ({message: 'This Failed'})

それから例えばあなたの try/catch

try {
//
} catch(e) {
    console.log(e); //{message: 'This Failed'}
    console.log(e.message); //This Failed
}

または単に文字列エラーをスローする

throw ('Your error')

try {
//
} catch(e) {
    console.log(e); //Your error
}

throw new Error //only accept a string

15

Errorコンストラクタは、エラーオブジェクトを作成するために使用されます。ランタイムエラーが発生すると、エラーオブジェクトがスローされます。Errorオブジェクトは、ユーザー定義の例外の基本オブジェクトとしても使用できます。

ユーザー定義エラーはthrowステートメントを介してスローされます。プログラム制御はcatch、呼び出しスタックの最初のブロックに渡されます。

Errorオブジェクトの有無によるエラーのスローの違い:


throw {'hehe':'haha'};

クロムでは、devtoolsは次のようになります。

ここに画像の説明を入力してください

Chromeは、単なるJSオブジェクトであるキャッチされていないエラーがあることを通知します。オブジェクト自体にエラーに関する情報が含まれている可能性がありますが、それがどこから発生したのかはすぐにはわかりません。コードで作業してデバッグしているときにはあまり役に立ちません。


throw new Error({'hehe':'haha'}); 

クロムでは、devtoolsは次のようになります。

ここに画像の説明を入力してください

Errorオブジェクトでスローされたエラーは、展開するとスタックトレースになります。これにより、エラーが正確に発生した場所に関する貴重な情報が得られます。これは、コードをデバッグするときに貴重な情報になることがよくあります。さらに、エラーに[object Object]はとあることに注意してください 。これは、Errorコンストラクターが最初の引数としてメッセージ文字列を期待しているためです。オブジェクトを受け取ると、文字列に変換します。


2

反応行動

残りの回答とは別に、Reactの違いを1つ示します。

をスローnew Error()して開発モードにすると、エラー画面とコンソールログが表示されます。文字列リテラルをスローすると、コンソールログを監視していない場合、文字列リテラルのみがコンソールに表示され、見逃す可能性があります。

エラーを投げてコンソールにログインする しながら開発モードで示すエラー画面(画面は、製造中に表示されません)。

throw new Error("The application could not authenticate.");

反応中のエラー画面

一方、次のコードはコンソールにのみログインします。

throw "The application could not authenticate.";
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.