論理演算子の&&は、左辺が偽であれば右辺を評価せず、||は、左辺が真であると右辺を評価しません。これは、今まで頂いたご回答に学ばせてもらって遅延評価というくくりの中の短絡評価と呼ぶものです。
ところで、なぜ&&の左辺が「偽」のときに右辺を評価せず、左辺が「真」のときに右辺を評価しない仕様なのでしょうか。逆に&&の左辺が真のときに右辺を評価せず、||の左辺が偽のときに右辺を評価しないという仕様では、ダメなのでしょうか。
何か背景となる根拠があってこのような形になったと思うのですが、いったいなぜこのような仕様なのでしょうか。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
ベストアンサー
&& や || が論理演算の 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/25 10:46
編集2016/07/25 10:48総合スコア2037
0
論理演算
論理演算には次の種類があります。
- 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 の場合のコード」を書きます。
JavaScript
1if (number >= 1 && number <= 10 && number % 1 === 0) { 2 console.log(number + ' は1以上10以下の整数です'); 3}
上記コードと同等の「&&
が NAND の場合のコード」を書きます。
JavaScript
1if (number < 1 && number > 10 && number % 1 !== 0) { 2 console.log(number + ' は1以上10以下の整数です'); 3}
NAND でも書けましたが、直観的ではないような気がします。
もし || が NOR だったなら
先程の「&&
が AND の場合のコード」を「||
が NOR の場合のコード」で書き直します。
JavaScript
1if (!(number >= 1 || number <= 10 || number % 1 === 0)) { 2 console.log(number + ' は1以上10以下の整数です'); 3}
このように NOT (!
) を併用する事で書けます。
次に「||
が OR の場合のコード」を書きます。
JavaScript
1if (typeof arg === 'number' || typeof arg === 'string') { 2 console.log(arg + ' は Number 型、もしくは String 型です'); 3}
上記コードと同等の「||
が NOR の場合のコード」を書きます。
JavaScript
1if (typeof arg !== 'number' || typeof arg !== 'string') { 2 console.log(arg + ' は Number 型、もしくは String 型です'); 3}
二重否定することで NOR は NOR で代用可能ですが、何とも回りくどい上に「二重否定するぐらいなら OR の方がシンプルで良い」という結論になってしまいます。
ちなみに、OR は NAND + NOT で代用することも可能です。
上記コードと同等の「&&
が NAND の場合のコード」を書きます。
JavaScript
1if (typeof arg === 'undefined' && arg === null && typeof arg === 'boolean' && typeof arg === 'symbol' && Object(arg) === arg) { 2 console.log(arg + ' は Number 型、もしくは String 型です'); 3}
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 さん
投稿2016/07/26 03:25
編集2016/07/26 03:26総合スコア18164
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
&&の左辺が真のときに右辺を評価せず、
||の左辺が偽のときに右辺を評価しないという仕様では、
ダメなのでしょうか。
それだとダメですね。
AND(&&)は両辺がTrueでTrue、残り3パターンはFalse
OR(||)は両辺がFalseでFalse、残り3パターンはTrue
ですから、ANDは一方が偽なら偽、ORは一方が真なら真、
と残った辺が真でも偽でもどちらでも真偽値が確定します。
なぜ&&の左辺が「偽」のときに右辺を評価せず、
左辺が「真」のときに右辺を評価しない仕様なのでしょうか。
真偽の逆はダメですが、左右は入れ替え可能です。
&&の右辺が偽のときに左辺を評価しない、
という仕様も(自分で言語を作るなら)可能でしょう。
ただ、自動車が右ハンドルの国と左ハンドルの国があるように、
いったんどっちかに決めたらルールを固定する必要があります。
後はささいな問題ですが、使う側の個人的意見として、
左辺を先に評価するので合ってると思います。
Javascript
1var flag = 'a' 2//var flag = '' 3var result = flag || 'b'; 4print(result);
上は一行目と二行目でコメントアウトを切り替えると、
代入される文字列が切り替わり、条件分岐を実現できます。
このように論理演算子の短絡評価を利用して、
条件文を省略する書き方があります。
(三項演算子と同じで、使うべきかどうかはともかく)
このとき、左が先に評価されて
実質的な条件判断になるのは、
if文の「if ( ) { }」と同じ順番なので、
この方が分かりやすいと思います。
投稿2016/07/25 11:50
総合スコア5592
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/07/26 10:21