Skip to content

Instantly share code, notes, and snippets.

@moriiimo
Last active December 16, 2015 00:09
Show Gist options
  • Save moriiimo/5344978 to your computer and use it in GitHub Desktop.
Save moriiimo/5344978 to your computer and use it in GitHub Desktop.
javascript : console.log([] == ![]); // true になるのはなぜか? 

#演算子の優位性

console.log([] == ![]); // true になるのはなぜか?

  1. [] はObjectになる。

     // 1. [] = 配列 = Object
     if ([] && [] instanceof Object) {
         console.log("true");
     } else {
         console.log("false");
     }
             // true になる
    
  2. 演算子は論理NOTの「!」が同値関係「==」よりも先に評価されるので、![] だと[]はオブジェクトであるのでfalseになる。 https://developer.mozilla.org/ja/docs/JavaScript/Reference/Operators/Operator_Precedence

             console.log(![]); // false
    
  3. 抽象的等価比較アルゴリズム(型変換を行う比較)で比較される。 http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma262r3/11_Expressions.html#section-11.9.3

3-1. 右辺がfalseになっているので、右辺が+0になる。

もしオペランドの片方が Boolean ならば、その論理オペランドは true ならば 1 に、そして false ならば +0 に変換されます。 via MOZILLA DEVELOPER NETWORK 比較演算子 https://developer.mozilla.org/ja/docs/JavaScript/Reference/Operators/Comparison_Operators

3-2. 右辺がプリミティブ型になっているので、左辺のオブジェクト型もプリミティブ型にされる。

比較対照がプリミティブ値である場合のみ、オブジェクトはプリミティブ値に変換されます。 via MOZILLA DEVELOPER NETWORK 比較演算子 https://developer.mozilla.org/ja/docs/JavaScript/Reference/Operators/Comparison_Operators

プリミティブ型に変換される場合はtoPrimitive( http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma262r3/9_Type_Conversion.html#section-9.1 )を通り、内部メソッド[[DefaultValue]] ( http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma262r3/8_Types.html#section-8.6.2.6 )がヒントなし呼ばれる。(オブジェクト型なので) その場合ヒントがNumberであるかのように振舞われる。おそらく以下と同じような結果が帰ってくる。

    var hoge = [];
    console.log(hoge.valueOf()); // [] が帰ってくる。
    console.log(hoge.toString()); // 空文字列になる。

3-3. 左辺が文字列になったため、数値に変換される。空文字は+0に変換される。

数値と文字列を比較するとき、文字列は数値に変換されます。JavaScript は文字列の数値リテラルを Number 型の数値に変換しようと試みます。最初に、その文字列の数値リテラルから数学的な値を引き出します。次に、最も近い Number 型の値にこの値を丸めます。 via MOZILLA DEVELOPER NETWORK 比較演算子

 空や空白である StringNumericLiteral は +0 に変換される。 via 9.3.1 String 型に適用される ToNumber

  1. +0 == +0 になるため、trueと出力された。

2. console.log(~~[] == 0); もtrueになるのはなぜか?

  1. ~ はビットごとのNOT(オペランドの各ビットを反転)の演算子.

ビット演算子は整数に対して使用されるため対象の値は32ビットの整数に変換されてから処理されます。

型変換のルールが適用されて、さきほどと同じ経路でオブジェクトが0になり、結果がtrueになる。

参考

MOZILLA DEVELOPER NETWORK 比較演算子 https://developer.mozilla.org/ja/docs/JavaScript/Reference/Operators/Comparison_Operators

Under Translation of ECMA-262 3rd Edition 8.型 http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma262r3/8_Types.html#section-8.6.2.6

Under Translation of ECMA-262 3rd Edition 9.型変換 http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma262r3/9_Type_Conversion.html#section-9.3.1

([] == ![])の謎 http://d.hatena.ne.jp/esperia/20110405/1302035204

http://www.ajaxtower.jp/js/ope/index8.html

http://wtfjs.com/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment