es-discuss@mozilla.orgメーリングリストのBrendanEichからの非常に迅速な応答:
Perlを考えてみましょう:
$ perl -e 'print 0 == "true";'
1
わかりました。論理的根拠は不十分ですが、1995年5月に、AWK、Perl 4、Python 1.2(IIRC)、TCLの陰でJSを作成しました。
与えられた私はPerlよりもAWKにもっと注意を払うべきだった
$ awk 'END {print(0 == "0")}'
1D
$ awk 'END {print(0 == "")}'
0D
ある意味で、JSの演算子は、NaNに変換することにより、Perl(変換などの非数値文字列)とAWK(変換のみ)==
の違いを分割します。そうすれば、少なくとも、"true"
0
"0"
0
js> 0 == ""
true
js> 0 == "true"
false
しかし、完全な真実は、私が他の言語を注意深くエミュレートしていたということではありません。むしろ、PHPのようなサーバー(LiveWire)にJS(当時は「Mocha」)を埋め込むために作業している一部のNetscaperは、ずさんな変換を望んでいたため、プログラマーはHTTPヘッダー文字列(サーバー側)またはHTMLフォームフィールド(クライアント側)を、たとえば、 404など。プログラマーによる明示的な強制はありません。
しかし、それは90年代でした、私は涙を流して急いでいました、これらの元ボーランドNetscapersは永続的でした。それで、去年のストレンジループで言ったように、「私はばかだった!彼らが望むものを彼らに与えた!」
暗黙の変換は、JSの急いで設計された私の最大の後悔です。'with'を含めても!
==演算子を使用したブール値と比較して、ブール値に変換しないという選択が行われた正確な理由を知っている人はいますか?
一般的な考え方は、狭いタイプは広くする必要があるということです。したがって、C ++の場合と同様に、ブール値をにtrue == 1
投影します。{false, true}
{0, 1}
true
しかし、あなたの例の他のオペランドはであるため、文字列に広げてみません"true"
か?良い質問。オペランドが数値またはブール値である場合に文字列を数値として比較する傾向は、HTTPヘッダーと数値文字列のHTMLフォームフィールドの使用例に起因します。繰り返しになりますが、これは正当な理由ではありませんが、JSが「機能する」方法です:-|。
これは、ECMA-262 Edition 5.1仕様、11.9.3抽象等式比較アルゴリズム、ステップ6および7(ステップ4および5に照らして読む)で確認できます。
4. Type(x)がNumberで、Type(y)がStringの場合、比較の結果x == ToNumber(y)を返します。
5. Type(x)がStringで、Type(y)がNumberの場合、比較の結果ToNumber(x)==yを返します。
6. Type(x)がブール値の場合、比較ToNumber(x)==yの結果を返します。
7. Type(y)がブール値の場合、比較の結果x == ToNumber(y)を返します。
Type(x)
これはすべて、とType(y)
forx == y
が同じではない大きな「else節」に含まれています。
申し訳ありませんが、ここには知恵の真珠(原文のまま)はありません。暗黙的な変換に加えて、データを失うことなく他のオペランドを保持できる最も狭い幅にオペランドを直接(中間変換なしで)広げない==
でください。!=
この数への狭められた文字列は単なる失敗です。
このボッチを修正した場合でも、次のようになります。
0 == "0"
1 == "1"
true != "1"
false != "0"
しかし、あなたの例が望むものもあります:
true == "true"
false != ""
文字列変換よりも数値の優先順位をボッチと呼んでいると、文字列から数値に狭まるため、true == "1"
またははありません。false == "0"
確かに、ナローイングはビットを失うことはなく、に戻って拡大することもできますが、0
==の暗黙の変換仕様から文字列に対するすべてのバイアスを削除するとどうなるかを説明するつもりでした。"0"
1
"1"
そのような変更は、Web上の多くのコードを壊しますか?私はそれがそうするであろう多額を賭けるでしょう。
一部の人は、内部での暗黙の変換に加えて、このボッチを、常に(変換しないため)使用===
し!==
、完全に回避する別の理由としてとらえ==
てい!=
ます。他の人は同意しません(特にテストするときx == null
、1人のオペレーターによる方法test x === null || x === undefined
)。
==
Webはほとんど互換性を持って成長するので、非常に古いフォームがなくなるまで、私たちはandに固執します。!=
したがって、ずさんな等式演算子が何をするかを学ぶことは有益だと思います。そうすれば、私には、それらが勝つ場所でそれらを使用できるように思われます。
typeof x == "function"
、など。
x == null
それ以外の場合は、とを使用===
し!==
ます。
オペランドが数値またはブール値である場合に文字列を数値として比較する傾向は、HTTPヘッダーと数値文字列のHTMLフォームフィールドの使用例に起因します。繰り返しになりますが、これは正当な理由ではありませんが、JSが「機能する」方法です:-|。
もう1つの注意:文字列から数値への絞り込みは、数値以外、空でない文字列から数値への暗黙の変換の試みが例外。
ここに、JSの設計ビットにおける別のパス依存バイアスがあります。ES3までJS1またはECMA-262標準での試行/キャッチはありません。
例外処理がないということは、そのようなプロパティがない場所でプロパティgetがundefined
欠落していることも意味します。それはまだ噛み付いています、おそらく暗黙の変換が噛むのと同じかそれ以上です。これは、Web JSの受賞歴のある「オブジェクト検出」パターンの基礎でもあり、これまでに見た他のすべてのバージョン管理スキーム、特に明示的な番号付けとオプトインに基づく事前のスキームをかなり上回っています。obj.foo
obj
==
時間をかけてオブジェクト検出用の実存演算子を追加すれば、次のように書くことができます。
function emulateRequestAnimationFrame(...) {...}
if (!window.requestAnimationFrame?)
window.requestAnimationFrame = emulateRequestAnimationFrame;
IOW、私がwindow.noSuchProperty
投げただけで真実であるwindow.noSuchProperty?
と評価した場合、またはfalse
(詳細はまだ未定です。「フェイルファストオブジェクト破壊」スレッドの復活、Nilのアイデアを参照してください)。