数学で多くの比較演算子を学びました。
JavaScriptでは、これらは次のように記述されます。
- より大きい/より小さい:
a > b
,a < b
。 - より大きい/より小さいまたは等しい:
a >= b
,a <= b
。 - 等しい:
a == b
, 等しいかどうかのテストは二重の等号==
で行うことに注意してください。一方、単一のa = b
は代入を意味します。 - 等しくない: 数学では
≠
と表記しますが、JavaScript ではa != b
と記述します。
この記事では、さまざまな種類の比較について、JavaScript がどのように行うか、重要な特徴を含めて詳しく学びます。
最後に、「JavaScript の癖」に関連する問題を回避するための良いレシピを見つけることができます。
真偽値が結果となる
すべての比較演算子は真偽値を返します。
true
– 「はい」、「正しい」、「真実」を意味します。false
– 「いいえ」、「間違っている」、「真実ではない」を意味します。
例:
alert( 2 > 1 ); // true (correct)
alert( 2 == 1 ); // false (wrong)
alert( 2 != 1 ); // true (correct)
比較結果は、他の値と同様に変数に代入できます。
let result = 5 > 4; // assign the result of the comparison
alert( result ); // true
文字列の比較
文字列が別の文字列より大きいかどうかを確認するために、JavaScript はいわゆる「辞書順」または「辞書式」順序を使用します。
言い換えれば、文字列は文字単位で比較されます。
例:
alert( 'Z' > 'A' ); // true
alert( 'Glow' > 'Glee' ); // true
alert( 'Bee' > 'Be' ); // true
2つの文字列を比較するアルゴリズムは簡単です。
- 両方の文字列の最初の文字を比較します。
- 最初の文字列の最初の文字が他の文字列の文字より大きい (または小さい) 場合、最初の文字列は2番目の文字列より大きい (または小さい) ことになります。これで完了です。
- それ以外の場合、両方の文字列の最初の文字が同じ場合は、2番目の文字を同じように比較します。
- いずれかの文字列の末尾まで繰り返します。
- 両方の文字列が同じ長さで終了した場合、それらは等しくなります。それ以外の場合、長い文字列の方が大きくなります。
上記の最初の例では、'Z' > 'A'
の比較は最初のステップで結果が出ます。
2番目の比較 'Glow'
と 'Glee'
は、文字列が文字単位で比較されるため、より多くのステップが必要になります。
G
はG
と同じです。l
はl
と同じです。o
はe
より大きいです。ここで終了します。最初の文字列の方が大きいです。
上記の比較アルゴリズムは、辞書や電話帳で使用されるアルゴリズムとほぼ同じですが、まったく同じではありません。
たとえば、大文字と小文字は区別されます。大文字 "A"
は小文字 "a"
と等しくありません。どちらが大きいでしょうか? 小文字の "a"
です。なぜでしょうか? 小文字は、JavaScript が使用する内部エンコードテーブル (Unicode) でより大きなインデックスを持っているからです。このことの詳細と結果については、文字列の章で詳しく説明します。
異なる型の比較
異なる型の値を比較する場合、JavaScript は値を数値に変換します。
例:
alert( '2' > 1 ); // true, string '2' becomes a number 2
alert( '01' == 1 ); // true, string '01' becomes a number 1
真偽値の場合、true
は 1
に、false
は 0
になります。
例:
alert( true == 1 ); // true
alert( false == 0 ); // true
同時に次のことが起こる可能性があります。
- 2つの値が等しい。
- それらのうちの1つは真偽値として
true
であり、もう1つは真偽値としてfalse
です。
例:
let a = 0;
alert( Boolean(a) ); // false
let b = "0";
alert( Boolean(b) ); // true
alert(a == b); // true!
JavaScript の観点からは、この結果はごく普通です。等価性チェックは数値変換を使用して値を変換しますが (したがって、"0"
は 0
になります)、明示的な Boolean
変換は別の規則セットを使用します。
厳密な等価性
通常の等価性チェック ==
には問題があります。0
を false
と区別できません。
alert( 0 == false ); // true
同じことが空の文字列でも起こります。
alert( '' == false ); // true
これは、異なる型のオペランドが等価演算子 ==
によって数値に変換されるためです。false
と同様に、空の文字列はゼロになります。
0
を false
と区別したい場合はどうすればよいでしょうか?
厳密な等価演算子 ===
は、型変換なしで等価性をチェックします。
言い換えれば、a
と b
が異なる型の場合、a === b
はそれらを変換しようとすることなく、直ちに false
を返します。
試してみましょう
alert( 0 === false ); // false, because the types are different
!=
に類似した「厳密な不等価」演算子 !==
もあります。
厳密な等価演算子は少し長く書く必要がありますが、何が起こっているかを明らかにし、エラーの余地を減らします。
null と undefined の比較
null
または undefined
が他の値と比較されると、直感に反する動作があります。
- 厳密な等価性チェック
===
の場合: -
これらの値は、それぞれが異なる型であるため、異なります。
alert( null === undefined ); // false
- 厳密でないチェック
==
の場合: -
特別なルールがあります。この2つは「甘いカップル」です。互いに等しい (
==
の意味で) が、他の値には等しくありません。alert( null == undefined ); // true
- 数学およびその他の比較
< > <= >=
の場合: -
null/undefined
は数値に変換されます。null
は0
になり、undefined
はNaN
になります。
それでは、これらのルールを適用したときに起こる面白いことをいくつか見てみましょう。そして、もっと重要なことですが、それらの罠に陥らない方法を見てみましょう。
奇妙な結果: null vs 0
null
をゼロと比較してみましょう。
alert( null > 0 ); // (1) false
alert( null == 0 ); // (2) false
alert( null >= 0 ); // (3) true
数学的には、それは奇妙です。最後の結果は「null
はゼロ以上である」と述べているため、上記の比較のいずれかで true
である必要がありますが、どちらも false です。
その理由は、等価性チェック ==
と比較 > < >= <=
の動作が異なるためです。比較では、null
を数値に変換し、0
として扱います。そのため、(3) null >= 0
は true であり、(1) null > 0
は false になります。
一方、undefined
と null
の等価性チェック ==
は、変換なしで、互いに等しく、他のものとは等しくないように定義されています。そのため、(2) null == 0
は false になります。
比較できない undefined
値 undefined
は、他の値と比較すべきではありません。
alert( undefined > 0 ); // false (1)
alert( undefined < 0 ); // false (2)
alert( undefined == 0 ); // false (3)
なぜゼロをそれほど嫌うのでしょうか? 常に false です!
これらの結果が得られる理由は次のとおりです。
- 比較
(1)
および(2)
は、undefined
がNaN
に変換され、NaN
がすべての比較でfalse
を返す特別な数値であるため、false
を返します。 - 等価性チェック
(3)
は、undefined
がnull
、undefined
とのみ等しく、他の値とは等しくないため、false
を返します。
問題を回避する
なぜこれらの例を検討したのでしょうか? これらの特徴を常に覚えておくべきでしょうか? まあ、そうではありません。実際、これらのトリッキーなことは時間の経過とともに徐々に馴染んでいきますが、それらによる問題を回避するための確実な方法があります。
- 厳密な等価性
===
を除く、undefined/null
との比較は例外的な注意を払って処理してください。 null/undefined
になる可能性のある変数で比較>= > < <=
を使用しないでください。何をしているのか本当に確信している場合を除きます。変数がこれらの値を持つ可能性がある場合は、それらを個別に確認してください。
まとめ
- 比較演算子は真偽値を返します。
- 文字列は、「辞書」順で文字単位で比較されます。
- 異なる型の値が比較されると、数値に変換されます (厳密な等価性チェックを除く)。
- 値
null
およびundefined
は、互いに==
で等しく、他の値とは等しくありません。 null/undefined
になる可能性のある変数で>
や<
などの比較を使用する場合は注意が必要です。null/undefined
を個別に確認することをお勧めします。
コメント
<code>
タグを使用し、複数行の場合は<pre>
タグで囲み、10 行を超える場合はサンドボックス (plnkr、jsbin、codepen…) を使用してください。