なぜワット

CodeMashに関するHarry Bernhardtの最近のレポートは非常に人気があることが判明しました(Transl 。: ハブを含む)。 レポートでは、彼はルビーとjavascriptの動作のいくつかの機能について冗談を言っています。

ハリーが不満を言っていることには意味があることを納得させることはできません。 ただし、javascriptがこのように動作する理由を説明できるといいのですが。



+シンボル



javascriptの+記号は、3つのことを意味します。



2つの数値に適用される2項加算演算子を使用できます。

2行に適用されるバイナリ行追加演算子を使用できます。

これは、1つの数値に適用される単項演算子「これは正の数値」です。



これにより、javascriptでの自動キャストが少し複雑になります。 たとえば、+文字の前後に文字列または数字がない場合、javascriptはオペランドを文字列または数字に自動的に変換します。



boolean, null, undefined



数値に変換されますtrue = 1, false = 0, null = 0, undefined = NaN





オブジェクト、配列、関数は文字列に変換されます



だからあなたが見るように

 [] + []
      
      





javascriptが両方の空の配列を文字列に変換し、結果の2つの文字列を追加することを理解しています。

配列が文字列に変換されると、コンマで区切られた要素のリストを含む文字列が取得されます。 したがって、空の配列の場合、空の文字列を取得します。



 [] + {}
      
      





この場合、右側の空のオブジェクトも文字列に変換されます。 彼は継承に従ってtoString



メソッドを実装していないため、 toString



Objectメソッドが使用され、 "[object Object]"



の文字列"[object Object]"



が返されます。 したがって、この例では、空の文字列を文字列"[object Object]"



に追加します。



空のコードブロック



ここで、javascriptパーサーの奇妙な点を検討します。 JavaScriptで中括弧を2つの異なる目的に使用していることに気づいたかもしれません。 コードのブロックを示し(たとえば、 if



後または関数定義の一部として)、オブジェクト表記でオブジェクトを記述します(JSONとも呼ばれます)。 一部のプログラミング言語では、既存のコード内の多くの場所でコードブロックを使用して、新しいスコープを定義できます。 (現時点では)Javascriptはコードブロックのレベルでスコープを使用しませんが、コード内でコードブロックを使用できます。 そのため、 {}



を記述するとき、javascriptパーサーはこれをコードの空のブロックとして、時には空のオブジェクトとして認識します。

一般的に、ブレースが式の先頭にある場合、コードのブロックの先頭として解釈されます。 javascriptパーサーに、通常の括弧で囲まれたオブジェクトとして扱うように強制できます。



 {} + []
      
      





この場合、空の中括弧は空のコードブロックとして扱われます。つまり、+は次のステートメントの先頭にあります。 後続の番号を正として指定する演算子として解釈されます。 プレフィックス演算子+は、単一の数値引数を入力として受け取るため、常に引数を数値にキャストします。



追加のトリックは、javascriptがオブジェクト、関数、または配列を数値にキャストし、最初にそれらを文字列にキャストすることです。 空の配列はゼロになります。 ここで、例えば:



 + [] === 0 /*        "",   0 */ + [1] === 1 /*        "1",   1 */ isNaN(+[1, 2] ) /*   ,  1, 2,   "1,2",     */ +({toString: function() {return "3"}}) === 3
      
      





そのため、空のオブジェクトは文字列"[object Object]"



NaN



れます。これは、プレフィックス演算子+により数値に変換する必要がある場合にNaN



NaN



されます。

 {} + {}
      
      







シンボル-



+とは異なり、シンボルは非常に単純です。 値は2つのみです。2つの数値に適用される2項演算子と、1つの数値に適用される接頭辞演算子です。 既にご存じのように、数字として使用されない文字列は、数字として使用される場合はNaN



されます。 したがって、驚くことはありません

 isNaN("wat" - 1) // true
      
      







なぜこれが重要なのですか?



実際に発生する可能性があるのは、これらのポイントのほんの一部です。 昔々、人々がJSONを解析するためにeval



を使用したとき、パーサーが誤ってそれをコードのブロックとして受け取らないように、JSONを括弧で囲む必要がありました。 変数の型を覚えて、文字列を数値に変換することがしばしば重要です。そうでなければ、人々は3 + 1 = 31を見ることに驚かれることでしょう。 そして、最も重要なことは、「javascriptが狂った」というレポートのリスナーになり、起こっていることがすべてあなたにとって完全に論理的であるかのように振る舞うことを可能にします。



All Articles