JavaScriptにおける値は、次のいずれかに分類できます:

typeof 演算子を使うと、 JavaScript の値が上記のどれに該当するか検査することができます(ただし、 null はオブジェクトとして判定され、関数は 'function' として判定されます)。

> typeof true
'boolean'
> typeof 123.45
'number'
> typeof 'hoge'
'string'
> typeof {x: 123}
'object'
> typeof Math
'object'
> typeof [1, 2, "hoge"]
'object'
> typeof Math.sqrt
'function'
> typeof (() => {})
'function'
> typeof Symbol()
'symbol'
> typeof null
'object'
> typeof undefined
'undefined'

値の等価性について

JavaScript の値の等価性を判定する方法はいくつか用意されています。

よく「JavaScript の等価性が奇妙だ」と言って槍玉に上がるのはイコールが2つの方で、イコールが3つの方を使えば変なことは起きません。

=== 演算子(イコールが3つ)

JavaScript の値の等価性を判定できます。

ただし、数値については、以下の注意点があります:

  • +0-0 は区別されません。
  • NaN はそれ自身と等価と判定されません。

多くのプログラミング言語で、浮動小数点数の等価性はこれと同じ挙動を示すので、 JavaScript が特別に奇妙だというわけではありません。

例:

> +0 === -0
true
> NaN === NaN
false

以下、 == との比較用:

> null === undefined
false
> "123" === 123
false
> "" === 0
false
> 1 === true
false
> 0 === false
false
> "[object Object]" === {}
false
> [] === 0
false
> "" === false
false
> [] === false
false

== 演算子(イコールが2つ)

== 演算子は === 演算子をベースに、不可解な挙動を加えたものです。新しく JavaScript を勉強する場合はこれを使う必要はありません。

x == y の動作は次の通りです:

  • x === y が true なら true
  • null と undefined の比較なら true
  • 数値と文字列の比較なら、文字列の方を数値に変換して比較する
  • 片方がブール値なら、それを数値に変換して(true: 1, false: 0) == で比較する(最初からやり直し)
  • 片方がオブジェクトで、もう片方が文字列、数値、シンボルのいずれかなら、オブジェクトをプリミティブ値に変換して == で比較する(最初からやり直し)
  • 上記いずれにも該当しないなら false

例:

> null == undefined
true
> "123" == 123 // 数値と文字列の比較(ステップ3)
true
> "" == 0 // 数値と文字列の比較(ステップ3)
true
> 1 == true // true は 1 に変換された上で比較される(ステップ4)
true
> 0 == false // false は 0 に変換された上で比較される(ステップ4)
true
> "[object Object]" == {} // 右辺のオブジェクトはプリミティブ値 "[object Object]" に変換される(ステップ5)
true
> [] == 0 // まずステップ5で配列 [] は空文字列 "" に変換される。次にステップ3の数値と文字列の比較で、空文字列 "" が 0 に変換される。
true
> "" == false // まずステップ4で false が 0 に変換される。次にステップ3で、空文字列 "" が 0 に変換される。
true
> [] == false // まずステップ4で false が 0 に変換される。次にステップ5で配列 [] は空文字列 "" に変換される。その次に、ステップ3で、空文字列 "" は数値 0 に変換される。
true

Object.is 関数

JavaScript の値の等価性を判定できます。

ただし、 +0-0 は区別され、 NaN 同士は等価として判定されます。

例:

> Object.is(+0, -0)
false
> Object.is(NaN, NaN)
true
> Object.is("", false)
false
> Object.is([], false)
false

演算子の一覧とその優先順位

1 + 2 * 3 と書いた場合に、 (1 + 2) * 3 ではなく 1 + (2 * 3) として解釈されることは皆さん分かっているかと思います。つまり、足し算よりも掛け算の方が優先順位が高いです。

以下に、演算子の一覧を優先順位の高いものから挙げて行きます。この一覧には、この入門記事で解説しない演算子も含まれます。

  1. メンバー参照 [], .
  2. 関数呼び出し ()
  3. 後置インクリメント、デクリメント ++, --
  4. (前置の)単項演算子:delete, void, typeof, ++, --, +, -, ~, !
  5. ベキ乗 ** (右結合)
    • ベキ乗演算子は ECMAScript 2016 で追加された。挙動は Math.pow と同じ。
    • 底の部分は、インクリメント以外の単項演算子は不可(- 2 ** 3 とは書けず、 (-2) ** 3- (2 ** 3) と書く必要がある)
  6. 乗算、除算、余り *, /, % (左結合)
  7. 加算、減算 +, - (左結合)
  8. ビットシフト <<, >>, >>> (左結合)
  9. 比較 <, >, <=, >=, instanceof, in (左結合)
  10. 等価性 ==, !=, ===, !== (左結合)
  11. ビットAND & (左結合)
  12. ビットXOR ^ (左結合)
  13. ビットOR | (左結合)
  14. 論理積 && (左結合)
  15. 論理和 ||(左結合)
  16. 三項演算子(の条件の部分) ? :
  17. 代入 =, *=, /=, %=, +=, -=, <<=, >>=, >>>=, &=, ^=, |= (右結合)
  18. カンマ , (左結合)