JavaScriptで「、、、」== Array(4)を使用する理由


119

インタプリタ/コンソールを起動して、比較してみてください

> ",,," == Array(4)
True

どうして?",,,"を、 '\ 0'で終わるスライスを持つ4つの文字の配列と考えることができるので、最初に考えたのはそのためかもしれませんが、

> "..." == Array(4)

「False」を返します。なぜ?私はそれがJavascriptでのアヒルのタイピングの特異なビットであることを知っていますが、この振る舞いを強調するものに興味があります。ところで、これをZed Shawの素晴らしいプレゼンテーションから集めました。


14
C以外のいくつかの言語は、プログラマーが認識できる方法でゼロ終了を使用します。
Joey

7
私が尋ねる場合、この発見につながるものは何ですか?
SomeKittens

1
@SomeKittens Zed Shawは、質問でリンクしたビデオでこれを明示的に言及しています(Javascriptの批判として)。乾杯!
ZenLikeThat

5
これは、RubyやJavaScriptでいくつかの癖を示し、(かなりよく知られている)「ワット」の話に記載されている@SomeKittens destroyallsoftware.com/talks/wat
Cronco

5
これは、の===代わりに常に使用する多くの正当な理由の1つです==
wprl

回答:


178

右側のオペランドは文字列に変換され、の文字列表現Array(4),,,次のとおりです。

> Array(4).toString()
  ",,,"

配列コンストラクター関数を使用して数値を渡すと、配列の長さがその数値に設定されます。したがって、4つの空のインデックス(と同じ[,,,])があり、配列のデフォルトの文字列表現は、その要素のコンマ区切りのリストであると言えます。

> ['a','b','c'].toString()
  "a,b,c"

比較の仕組みについては、仕様のセクション11.9.3で説明しています。そこに(x == y)が表示されます:

8. Type(x)がStringまたはNumberで、Type(y)がObjectの場合
、比較の結果x == ToPrimitivey)を返します。

(配列はJavaScriptのオブジェクトです)

そして、ToPrimitiveメソッドに従うと、最終的にそれが呼び出すことがわかりますtoString


2
さて、今、これはすべて私にとって理にかなっています。ありがとう。
ZenLikeThat

6
これは、配列がを使用しているかのように文字列化するためArray.join(",")です。
duskwuff -inactive-

JavaScriptでプログラミングするには血なまぐさい患者でなければなりません
マッチク


31

を使用してみてください=====JavaScriptで使用すると、変数をキャストしようとするため、このような問題が発生します。コンソールはArray(4)文字列表現(つまりArray(4).toString)にキャストしています",,,"。カンマが存在する理由は、.toString()関数が配列内の個別の項目にそれらを追加するためです。

以下のスニペットをご覧ください。

document.write( Array(4).toString() );


18

これはArray(4)、4つの空の値の配列を初期化し、==暗黙的に変換するためです。

 ",,," == Array(4)

 ",,," == Array(4).toString()

 ",,," == ["", "", "", ""] // note 3 commas for 4 values

 ",,," == ["", "", "", ""].toString()

すべて似ています。

==値を比較する前に暗黙の型変換を行うため、予期しない結果が生じる可能性があります。===タイプと値を確認するために使用します。


5

配列を文字列と比較すると、比較を行う前に配列が文字列に強制変換されます。空の4要素配列を文字列に強制変換すると、その正確な文字列が生成されます。


4

最初は「プロトタイプ」の問題だと思っていました...少し調査した結果、悲しい結論に達しました...

どうやらそれはあまり論理的ではない内部的でより曖昧なjsのものです...

ちょうど試して

Array(4)==Array(4)

タイプにも強制はありません...

Array(4)===Array(4)

そしてあなたはFALSEを取得します

あなたはそれを知っているnull==nullnull===nullとさえundefined==undefinedしてundefined===undefinedtrueを返します...そう...それは少しあいまいです...

Array(4)==[,,,] また真実でなければなりません


ZEE、Array(4)== [,,,]は真ではありません。オブジェクトをプリミティブと比較すると、オブジェクトはプリミティブに変換されます。それがtoString()を呼び出す理由です。
devsathish

array(x)はコンストラクタのアドレスにする必要があります...とにかく、システムでは(どのようなシステムでもかまいません)、<identity_X> === <identity_X>は常にtrueになるはずです!
ZEE
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.