30116

[code]

    if ([] == false && []) {
        console.log("True");
    } else {
        console.log("False");
    }
    
[/code]

なぜ実行結果が **True** になるのでしょうか？  
内部的にはどのように評価されているのでしょう？


CC BY-SA 3.0
2016-11-05T07:42:27.743
30115
2016-11-05T11:24:43.113
2016-11-05T11:24:43.113
5519
19439
question
javascript
空配列を条件式で使った場合の論理演算の結果が分からない


`==`は様々な暗黙のデータ変換を行ったのちに比較が行われますから、時に予想外の結果を返すこともあります。

まずは、`&&`の右側ですが、`[]`はbooleanに変換される場合、`true`になります。(JavaScriptの配列はobjectの一種ですが、objectは中身が見かけ空であってもtrueになります。)

[ECMAScript® 2015 Language Specification](http://www.ecma-
international.org/ecma-262/6.0/)

[7.1.2 ToBoolean ( argument )](http://www.ecma-
international.org/ecma-262/6.0/#sec-toboolean)

> ...
>
> Object | Return **`true`**.

ややこしい闇の奥底を覗き込まないといけないのは、左辺の方で、以下に示すリンク先のあちこちを追わないと何が起こっているのか理解できなくなります。

[7.2.12 Abstract Equality Comparison](http://www.ecma-
international.org/ecma-262/6.0/#sec-abstract-equality-comparison)

詳細を追っていくのは大変なので、要約すると:

  * `==`の右辺のbooleanは、numberに変換される(結果は`0`)

  * `==`の左辺objectは、まずstringに変換され(結果は`""`)、その後numberに変換される(結果は`0`)

よって、`[] == false`は真。

* * *

わたしも調べなおしてみるまでは、まず`[]`がbooleanに変換されてから比較されるので、`true ==
false`と同値、つまり`false`を返すと思い込んでいました。`==`にまつわる変換で何が起こるのか熟知していない限り、`==`はできる限り使わない、と言うのは正しい選択のようです。


CC BY-SA 3.0
2016-11-05T08:30:28.030
30116
2016-11-05T08:30:28.030
13972
30115
answer


`==`と`&&`だと`==`の優先度が高いので、`[] == false`がまず評価され、その結果と`[]`との論理積が計算されます。

論理演算において`[]`はtrueになるので、あとは`[] == false`がtrueになればいいわけですが、これは以下の様に評価されます。

  1. falseが+0に変換される: `[] == +0`
  2. `[]`が`toString()`により空文字列に変換される: `"" == +0`
  3. 空文字列が数値に変換される(i.e. `Number("")`): `0 == +0`
  4. オペランドがともに0なのでtrueに評価される。


CC BY-SA 3.0
2016-11-05T08:41:04.610
30117
2016-11-05T09:00:03.640
2016-11-05T09:00:03.640
5044
19437
30115
answer