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

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

ただいまの
回答率

87.95%

逆ではダメなのか

解決済

回答 5

投稿

  • 評価
  • クリップ 0
  • VIEW 2,122

score 481

論理演算子の&&は、左辺が偽であれば右辺を評価せず、||は、左辺が真であると右辺を評価しません。これは、今まで頂いたご回答に学ばせてもらって遅延評価というくくりの中の短絡評価と呼ぶものです。
ところで、なぜ&&の左辺が「偽」のときに右辺を評価せず、左辺が「真」のときに右辺を評価しない仕様なのでしょうか。逆に&&の左辺が真のときに右辺を評価せず、||の左辺が偽のときに右辺を評価しないという仕様では、ダメなのでしょうか。
何か背景となる根拠があってこのような形になったと思うのですが、いったいなぜこのような仕様なのでしょうか。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

checkベストアンサー

+3

&& や || が論理演算の AND OR に対応していることは理解していますよね。

  • (TRUE) AND (TRUE) = TRUE
  • (TRUE) AND (FALSE) = FALSE
  • (FALSE) AND (TRUE) = FALSE
  • (FALSE) AND (FALSE) = FALSE

左項がTRUEの場合、結果が確定しません(右項の結果によります)。
左項がFALSEの場合、右項がなんであれFALSEで確定します。
そのため、左項がFALSEの場合、右項を評価する必要はありません。

  • (TRUE) OR (TRUE) = TRUE
  • (TRUE) OR (FALSE) = TRUE
  • (FALSE) OR (TRUE) = TRUE
  • (FALSE) OR (FALSE) = FALSE

ORの場合、左項がFALSEでも右項によっては式全体はTRUEになります。
そのため、左項がFALSEの際に右項を評価しないわけには行きません。
逆に左項がTRUEであれば、右項によらずTRUEで確定します。
つまり右項を評価する必要はなくなります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/26 19:21

    ご回答有難うございました。
    説明して頂いてみると確かにそうですね。必要ないものを態々評価する必要は無いです。なんで気づかなかったんだろう。凄く腑に落ちました。

    キャンセル

+3

どっちでもいいから決まってないとプログラムが組めません。
左から読むので左から評価するのが自然だと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

&&の左辺が真のときに右辺を評価せず、
||の左辺が偽のときに右辺を評価しないという仕様では、
ダメなのでしょうか。

それだとダメですね。

AND(&&)は両辺がTrueでTrue、残り3パターンはFalse
OR(||)は両辺がFalseでFalse、残り3パターンはTrue

ですから、ANDは一方が偽なら偽、ORは一方が真なら真、
と残った辺が真でも偽でもどちらでも真偽値が確定します。


なぜ&&の左辺が「偽」のときに右辺を評価せず、
左辺が「真」のときに右辺を評価しない仕様なのでしょうか。

真偽の逆はダメですが、左右は入れ替え可能です。
&&の右辺が偽のときに左辺を評価しない、
という仕様も(自分で言語を作るなら)可能でしょう。

ただ、自動車が右ハンドルの国と左ハンドルの国があるように、
いったんどっちかに決めたらルールを固定する必要があります。


後はささいな問題ですが、使う側の個人的意見として、
左辺を先に評価するので合ってると思います。

var flag = 'a'
//var flag = ''
var result = flag || 'b';
print(result);

上は一行目と二行目でコメントアウトを切り替えると、
代入される文字列が切り替わり、条件分岐を実現できます。

このように論理演算子の短絡評価を利用して、
条件文を省略する書き方があります。
(三項演算子と同じで、使うべきかどうかはともかく)

このとき、左が先に評価されて
実質的な条件判断になるのは、
if文の「if ( ) { }」と同じ順番なので、
この方が分かりやすいと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/26 19:45

    ご回答有難うございました。
    確かに人間の目は、ものを見るとき左から右へ視点を動かすと聞きます。
    だから右より先に左で評価しているのでしょう。

    キャンセル

+1

 論理演算

論理演算には次の種類があります。

  • NOT (否定) … 「NOT A」は「A ではない」を表す。JavaScript では ! で表す。
  • AND (論理積) … 「A AND B」は「A かつ B」を表す。JavaScript では A && B で表す。
  • OR (論理和) … 「A OR B」は「A または B」を表す。JavaScript では A || B で表す。
  • NAND (否定論理積) … 「A NAND B」は「A ではなく B でもない」を表す。JavaScript の論理演算子には存在しない。
  • NOR (否定論理和) … 「A NOR B」は「A ではない、または B ではない」を表す。JavaScript の論理演算子には存在しない。

aaaaaaaa さんが提案している方法は NAND と NOR です。

 if 文

論理値を反転させるならば「if 文の条件が偽ではいけないのか」という考えにも行き着きますが、if 文は「もし~ならば」の制御構文なので条件が真である必要があります。

 もし && が NAND だったなら

&& が AND の場合のコード」を書きます。

if (number >= 1 && number <= 10 && number % 1 === 0) {
  console.log(number + ' は1以上10以下の整数です');
}

上記コードと同等の「&& が NAND の場合のコード」を書きます。

if (number < 1 && number > 10 && number % 1 !== 0) {
  console.log(number + ' は1以上10以下の整数です');
}

NAND でも書けましたが、直観的ではないような気がします。

 もし || が NOR だったなら

先程の「&& が AND の場合のコード」を「|| が NOR の場合のコード」で書き直します。

if (!(number >= 1 || number <= 10 || number % 1 === 0)) {
  console.log(number + ' は1以上10以下の整数です');
}

このように NOT (!) を併用する事で書けます。
次に「|| が OR の場合のコード」を書きます。

if (typeof arg === 'number' || typeof arg === 'string') {
  console.log(arg + ' は Number 型、もしくは String 型です');
}

上記コードと同等の「|| が NOR の場合のコード」を書きます。

if (typeof arg !== 'number' || typeof arg !== 'string') {
  console.log(arg + ' は Number 型、もしくは String 型です');
}

二重否定することで NOR は NOR で代用可能ですが、何とも回りくどい上に「二重否定するぐらいなら OR の方がシンプルで良い」という結論になってしまいます。

ちなみに、OR は NAND + NOT で代用することも可能です。
上記コードと同等の「&& が NAND の場合のコード」を書きます。

if (typeof arg === 'undefined' && arg === null && typeof arg === 'boolean' && typeof arg === 'symbol' && Object(arg) === arg) {
  console.log(arg + ' は Number 型、もしくは String 型です');
}

NAND でも書けましたが、条件が多くなり、可読性が低くなってしまいました。
(逆に言えば、OR 条件が多ければ NAND 条件が少なくなるという事でもあります。)

 不公平な比較

ここまでは「AND, OR 条件を NAND, NOR 条件で書き換えるにはどのように書くか」という視点でコードを書いてきました。
これは元々の論理が AND, OR で構成されているので NAND, NOR に書き換える事で複雑化しているように読めますが、初めから NAND, NOR で条件を考えるなら NAND, NOR が適している状況もある、といえます。
しかし、私の感覚としては人間の頭は AND, OR で物事を考える方が直観的に受け入れやすいように思います。
勿論、あくまで私の感覚的なものなので「NAND, NOR の方ががわかりやすい」という人もいると思いますが…。

 思考実験

「もし~だったならダメなのか」と疑問をもったならば、その状況になった場合のコードを考えてみると更に一歩踏み込んだ質問になってよいと思います。
この手の思考実験は想像するだけでも楽しいですが、実際にコードを書いてみるとわかりやすいですね。
ここで紹介したコードは全てコンソールで実験しています。
具体的には (!A && !B) と書く事で NAND とし、最後に ! を取り除きました(NOR も同様です)。

Re: aaaaaaaa さん

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

例えば if (評価A) || (評価B) || (評価C) の様な場合、それぞれの評価を処理(proc)として結果を返すルーチンとして作成する事が有ります。||の場合、Aが正常であればB(処理)は行わない、またはAが異常であればBを行う。また、&&で有れば、Aが正常ならBを行うという様に使っています。
評価=実行のイメージです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 87.95%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る