JavaScriptのifステートメントに複数の条件が含まれている場合、それらすべてがテストされますか?


100

javascriptで、複数の条件をテストするifステートメントを使用する場合、javascriptはそれらすべてに関係なくテストしますか、それとも既にfalseの場合、すべてをテストする前に保釈しますか?

例えば:

 a = 1
 b = 2
 c = 1

 if (a==1 && b==1 && c==1)

javascriptはこれらの3つの条件すべてをテストしますか、またはbが1と等しくないためにfalseであることを確認した後、ステートメントを終了しますか?

パフォーマンスの観点からお願いします。たとえば、3つの複雑なjQueryセレクターをテストしている場合、最初の1つを介してFALSEを返すことが明らかな場合、jQueryがDOMを3回トラバースしないようにします。(その場合、3つのifステートメントをネストする方が理にかなっています)。

補遺:好奇心よりも、これの適切な用語は何ですか?多くの人が「短絡」という用語を使用していることに気づきました。また、一部の言語はこれを行い、他の言語は行いませんか?


@ジョシュ:これはマイクロ最適化であるという考えに完全に感謝します。知っておくと便利です。とはいえ、1つのオプションが別のオプションよりも最適化されている場合は、この方法を使用する習慣を身につけて習得することは良いことだと思います。(それに加えて、私もその答えを知りたがっていました)
DA。

21
厳密に言えば、これは時期尚早の最適化ではありません。ショートサーキットロジックを使用する言語では、一部のメソッドが実行されない条件を把握することが重要です。たとえば、あなたが彼らの副作用に頼っているなら。
Rob

5
:ここでは「短絡評価」については、別の問題だstackoverflow.com/questions/1232603/...
デヴィッド・

@David。ありがとう!興味深い読書。
DA。

回答:


151

&&オペレータ「短絡」 -左の条件が偽であれば、それは正しいものを評価する気にしない、です。

同様に、||左の条件が真の場合、演算子は短絡します。

編集:ただし、ベンチマークを行い、それが問題であると判断するまで、パフォーマンスについて心配する必要はありません。早期のマイクロ最適化は、保守性の悩みの種です。


1
すばらしい答え(技術的な部分と管理上の問題の両方)。ありがとう!
DA。

5
ブール値の文のすべての部分を実行したい場合は、&と|を使用できます。および/またはそれぞれに
Zoidberg

25
この状態は必ずしもパフォーマンスに関するものとは限りません。場合によっては、nullチェックを実行していて、nullチェックが条件aであると言ってから、2番目のチェックで(b ==値+ 1)を実行しようとすると、条件がチェックされている場合、3つの条件すべてがエラーになります。
infocyde 2009

4
確かに、短絡はパフォーマンスの問題ではありません。ただし、元の質問はパフォーマンスの観点から尋ねていました。
アノン。

1
とても良い。(特に)この種のマイクロ最適化を実行すると、スクロールイベントループ内で大きな影響が出る可能性があります。たとえば、複数の要素の視差計算や、粘着性のある棒などです。この例を見てくださいif (!barSticky && bar.parent().offset().top <= document.documentElement.scrollTop)。2番目の条件はよりコストのかかる計算で、最初の条件は単なるブール値です。:)
antoni 2016年

13

パフォーマンスの観点からは、これはマイクロ最適化ではありません。

3つのブール変数a、b、cがある場合、これはマイクロ最適化です。

ブール変数を返す3つの関数を呼び出す場合、各関数には長い時間がかかる可能性があり、この短絡を知ることだけでなく、その順序を知ることも重要です。例えば:

if (takesSeconds() && takesMinutes())

よりはるかに優れています

if (takesMinutes() && takesSeconds())

両方が等しくfalseを返す可能性が高い場合。


12

それがあなたがのようなJavaScriptコードで行うことができる理由です

var x = x || 2;

つまり、xが未定義であるか「false」の場合、デフォルト値は2になります。


3
これは、JSが短絡評価をサポートしていなくても機能します。
pswg 2014

1
これは三項に相当しますか?
Mark Carpenter Jr

10

すべての条件の評価強制する方法があるかどうか疑問に思っている場合は、ビットごとの演算子&|使用して、

var testOr = true | alert(""); //alert pops up
var testAnd = false & alert(""); //alert pops up

ビット演算子はオペランドの単一ビットで機能する算術演算子であり、常に「非短絡」バージョンとして機能することができないため、これらは慎重に使用する必要が&&あります。||

例:

-2147483648 && 1 = 1 

だが

-2147483648 & 1 = 0

このような情報を探してここに到着した人(私のような)を助けてくれれば幸いです。修正と反例については@Maxに感謝します


1
この答えは間違っています。&および| ビット演算子であり、「&&と||の非短絡バージョン」ではありません。ビット演算子は、オペランドの単一ビットで機能する算術演算子です。例:-2147483648 && 1 = 1、ただし-2147483648&1 =0。詳細はこちら:en.wikipedia.org/wiki/Bitwise_operation
Max

1
@Maxは実際にはこれを知りませんでした。Cを勉強して以来、これを使用しています(現在は "トリック"と呼んでいます)。私は私の答えを訂正しました、私はあなたに借りがあります
ivcandela '25

@DJDaveMark申し訳ありませんが、false && (alert(""))ソリューションを機能させることができませんでした:/
ivcandela

@ivcandelaどちらもできませんでした。電話に出ていなかった場合、最初にテストしました; o)残念ですが、コメントを編集することはできません。削除して下に追加しました
DJDaveMark

力の評価に単純でより良い方法は、変数に対するテストは、IEの変数に結果を保存することです:var a=false; var b=check(); alert(a && b);
DJDaveMark

7

最初の条件が真の場合にのみすべての条件をテストします。自分でテストしてください:

javascript: alert (false && alert("A") && false);


3

左側の1つ以上のパラメーターで評価を停止するもう1つの理由。

if(response.authResponse &&(response.authResponse.accessToken!= user.accessToken)){...}

2番目の評価は最初の条件がtrueであることに依存し、response.authResponseがnullまたは未定義の場合、最初の条件が失敗したためにコンパイルエラーをスローしません。

他の言語では初期の段階でこの問題がありましたが、今ではコンパイラを構築するための標準的なアプローチだと思います。



2

次のような演算子||と組み合わせてを使用すると、短絡動作が見られないため、この質問の誰もが混乱しました?

x = 1 || true ? 2 : 3 // value of x will be 2, rather than 1 as expected

短絡ルールが機能していないようです。||(true?2:3)の2 番目の項が最初の項がtrueであるのに、なぜそれが評価されるのですか?上記は次と同等であるため、操作の順序の問題であることがわかります

x = (1 || true) ? 2 : 3

||最初に評価し、?第二の評価します。あなたが望んでいるのは:

x = 1 || (true ? 2 : 3)

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