19

このコードでより効率的なものについて、他の意見が欲しいです。基本的に、次のコードには setInterval ループがあり、コードがループ内で実行される前に 4 つの要件を満たす必要があります。したがって、v.1 では、4 つすべてをチェックする if ステートメントを書きました。うまくいきました。

次に、実行したいコードを try{} に置いて、try/catch のみを使用するように切り替えました。ロジックは、各ループ中に例外が生成されますが、無効な条件ごとに抑制されます。すべての条件が真である最後のループで、コードが実行され、間隔がクリアされます。

どちらでも動作します。私が try/catch メソッドを気に入っているのは、書く必要があり、壊れることを心配する必要のある条件付きコードが少ないからです。しかし、特に setInterval() ループが 100 ミリ秒に達した場合に、try/catch が本当に非効率的ではないかと心配しています。SOに関する他の明るい人の意見は何ですか?

トライ/キャッチ

var intvar = setInterval(function(){
try{    
    clearInterval(intvar);

    jQuery('#'+nav[pageid].t1+'>a').replaceWith(jQuery('<span>'+jQuery('#'+nav[pageid].t1+'>a').text()+'</span>'));

    //set display classes for nav
    jQuery('#'+nav[pageid].t1).addClass('selected').find('#'+nav[pageid].t2).addClass('subselect'); //topnav
    jQuery('#'+nav[pageid].t3).addClass('selected').find('#'+nav[pageid].t4).addClass('subselect'); //leftnav
}catch(err){}
},100);

IF ブロック

var intvar = setInterval(function(){

if(typeof jQuery == 'function' && typeof nav == 'object' && typeof pageid != 'undefined' && typeof document.getElementById('leftnav') == 'object'){
    clearInterval(intvar);
    jQuery('#'+nav[pageid].t1+'>a').replaceWith(jQuery('<span>'+jQuery('#'+nav[pageid].t1+'>a').text()+'</span>'));

    //set display classes for nav
    jQuery('#'+nav[pageid].t1).addClass('selected').find('#'+nav[pageid].t2).addClass('subselect'); //topnav
    jQuery('#'+nav[pageid].t3).addClass('selected').find('#'+nav[pageid].t4).addClass('subselect'); //leftnav
}

},100);
4

7 に答える 7

21

例外は、例外的な状況(つまり、通常は発生しないと予想されるもの)に使用する必要があります。一般に、ifステートメントでテストできるものをキャッチするために例外を使用するべきではありません。

また、私が理解していることから、例外はifステートメントよりもはるかに高価です。

于 2009-02-17T22:07:18.423 に答える
18

ifステートメントを使用します。TRY / CATCHのオーバーヘッドが何であるかはわかりませんが、ブール式を評価するよりもはるかに大きいと思います。TRY / CATCHを実行するには、ステートメントを実行し、[関連するオーバーヘッドを使用して]エラーを生成し、エラーをログに記録し(おそらく)、スタックトレースを作成し(おそらく)、コードに戻ります。さらに、これらの行の近くでコードをデバッグする必要がある場合、実際のエラーは、試行/キャッチしているもので難読化される可能性があります。

さらに、これはTRY / CATCHの誤用であり、コードを非常に読みにくくする可能性があります。より長い、またはより難解なケースでこれを行うと仮定しますか?あなたのキャッチはどこに行き着くのでしょうか?

これは、例外処理と呼ばれます

編集:以下にコメントするように、実際に例外が発生した場合にのみ、実行時のパフォーマンスが低下します。

于 2009-02-17T22:12:12.467 に答える
12

他の答えは正しく、try/catch例外的な状況とエラー処理のためのものです。 if条件はプログラム ロジック用です。「どっちが速い?」は間違った質問です。

経験則として、例外に対して何もしていない場合、それはおそらく例外ではありません!

どちらを使用するかを理解するために、if 条件を分解してみましょう。

  1. typeof jQuery == 'function' jQuery() 関数は定義されていますか?
  2. typeof nav == 'object' nav グローバル変数にはオブジェクトが含まれていますか?
  3. typeof pageid != 'undefined'pageid グローバル変数は定義されていますか?
  4. typeof document.getElementById('leftnav') == 'object' ドキュメントに leftnav 要素が含まれていますか?

最初のものは明らかに例外です。jQuery() 関数がなければ、うまくいきません。

2番目も例外です。nav オブジェクトがなければどこにも行けません。

3番目は例外です。何をするにもページIDが必要です。

4番目はおそらく論理です。「leftnav 要素がある場合にのみ、このコードを実行します」。コードの残りの部分は leftnav 要素を参照していないため、見分けるのは困難です。コメントだけがそうです、赤い旗。したがって、おそらくプログラミングのミスです。

したがって、私はおそらくこれを行うでしょう(jQueryを解体している場合はお詫びします):

var intvar = setInterval(function() {
    // If there's no leftnav element, don't do anything.
    if( typeof document.getElementById('leftnav') != 'object') {
        return;
    }

    try {
        clearInterval(intvar);
        jQuery('#'+nav[pageid].t1+'>a')
            .replaceWith(jQuery('<span>'+jQuery('#'+nav[pageid].t1+'>a').text()+'</span>'));

        //set display classes for nav
        jQuery('#'+nav[pageid].t1)
            .addClass('selected')
            .find('#'+nav[pageid].t2)
            .addClass('subselect');     //topnav
        jQuery('#'+nav[pageid].t3)
            .addClass('selected')
            .find('#'+nav[pageid].t4)
            .addClass('subselect');     //leftnav
    }
    catch(err) {
        ...do something with the error...
    }
},100);

...しかし、 leftnav 要素チェックが適用可能かどうかを実際に調べたいと思います。

最後に、この「関数」がグローバル変数を操作しているとコメントせずにはいられません。カプセル化と正気を維持するために、代わりにnavandを関数に渡す必要があります。pageid

于 2009-02-18T06:29:48.120 に答える
3

私は次のコードを書きます:

var startTime = (new Date()).getTime();
for (var i=0; i < 1000; ++i) intvar();
var endTime = (new Date()).getTime();
alert("Took " + ((endTime - startTime) / 1000.0) " seconds");

次に、両方のバージョンのintvarを試して、どちらがより高速に実行されるかを確認します。私はこれを自分で行いますが、ページレイアウトがないため、コードが機能しません。

いくつかの文体的​​なコメント-それが関数であるかどうかをテストする必要はないようですjQueryintvarそうでない場合は、コードを実行しないと役に立たないように、Webページが混乱している可能性があります。例外がスローされることをめったに期待しない場合は、try/catchを使用します。

于 2009-02-17T22:07:39.450 に答える
2

とにかく実行する必要があるコード ブロックを try/catch でラップする (何か恐ろしいことが起きない限り) 提供されている例では、try/catch を使用するのが適切な形式です。あなたの類推: あなたはいつも「空は青いですか?」とテストしますか? if ステートメントで、または空がたまたま緑に変わったときにのみトリガーされる try/catch でラップしますか。

ユーザー提供の入力を処理している場合、またはコード内で別のことが起こっているために関数が存在しない可能性が非常に高い場合は、If ステートメント メソッドを使用します。

例外をトリガーしない場合は、コード全体で巻き戻しやバックトラックがないことに注意してください。この例では、catch は何かが間違っている場合 (jQuery が欠落しているなど) にのみ実行されますが、if ステートメント メソッドでは、その関数へのすべての SINGLE CALL で評価が行われます。必要以上の作業を行うべきではありません。 .

于 2009-02-17T23:51:03.447 に答える
0

質問に直接答えると、他の誰もがそうであるように、実際にエラーが発生した場合、try..catch のコストが高くなる可能性があります。

他の人がすでに指摘したものを超えて、コード内のいくつかの追加エラーを指摘するには:

これら 2 つのコードはまったく同等ではありません。説明すると、コードはまったく同じことをしているように見えますが、そうではありません。

if() チェックの場合、コードは何も実行されません。例外ハンドラの場合、例外ハンドラ内のコードの各行が実行されます。SO、2 行目または 3 行目でエラーが発生した場合はどうなりますか? 次に、コードを実行する前に条件をチェックした場合とはまったく異なることがコードで起こっています。

于 2014-04-18T02:28:39.663 に答える