20
8

More than 5 years have passed since last update.

JSにおける [] == ![] がわからなかったので、true に至る道を辿ってみました。

Last updated at Posted at 2016-12-07

参考にしたページはこちらです。
- http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness

問題

問題
[] == ![] // これはなんですか?

道のり1

まず、右辺が考えやすいので、右辺を考えます。

Boolean([]) // => true

ですので、

![] // => false

となります。よって

書き換え1
[] == false

道のり2

ここで 11.9.3 The Abstract Equality Comparison Algorithm によります。 ※ 以下、何度か参照します。

スクリーンショット 2016-12-07 12.47.37.png

7: If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).

上の項目に該当すると思います。それに沿って右辺を number にします。

Number(false) // => 0

ですので、次のように書き換えれます。

書き換え2
[] == 0

道のり3

続いて

9: If Type(x) is Object and Type(y) is either String or Number,
return the result of the comparison ToPrimitive(x) == y.

上に該当します。

ここで、挫折しました。 ToPrimitive(x) が全然分かりません。

しばらく迷子になった後、

以下の記述を Equality comparisons and sameness に出会いました。

ToPrimitive(A) attempts to convert its object argument to a primitive value, by attempting to invoke varying sequences of A.toString and A.valueOf methods on A.

「ToPrimitive(A)は、 toString や valueOf メソッドをつかって、 A を primitive な値に変換しようとする。」と解釈しました。

ですので、以下の操作から、 [] の primitive値は "" となります。

primitive値をもとめたい
[].valueOf() // => [] これは primitive じゃない
[].toString() // => "" これは primitive です

したがって、左辺を primitive にして以下のようになります。

書き換え3
"" == 0

道のり4(おしまい)

最後に、

5: If Type(x) is String and Type(y) is Number,
return the result of the comparison ToNumber(x) == y.

こちらに従うことで、

Number("") // => 0
書き換え4(おしまい)
0 == 0 // => true

以上です。ありがとうございました。

20
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
8