2012-01-21 10 views
5

私はRubyやJavaScriptのような言語では、いくつかの奇妙について昨日、このかなり面白いscreencastを見てきましたし、男がいることを示しています。私は行くことに決めました...Array + Arrayが空の文字列と等しいのはなぜですか?

[] + [] -> "" // returns empty string 

ない非常に明白

より多くの情報を取得するECMAscript language specification

11.6.1加算演算子(+)

加算演算子のいずれかの文字列の連結または数値加算を実行する:私は言う+オペレータの実装(P.75)を始めました。
AdditiveExpression:AdditiveExpression + MultiplicativeExpressionは、次のように評価されます。
1. AdditiveExpressionを評価した結果をlrefとします。
2. lvalをGetValue(lref)とします。
3. MultiplicativeExpressionを評価した結果をrrefとします。
4. rvalをGetValue(rref)とします。
5. lprimをToPrimitive(lval)にします。
6. rprimをToPrimitive(rval)にします。
7.タイプ(lprim)がストリングまたはタイプ(rprim)がストリングの場合、
a。 ToString(lprim)とToString(rprim)を連結した結果の文字列を返します。
8. ToNumber(lprim)とToNumber(rprim)に加算演算を適用した結果を返します。 11.6.3の注を参照してください。

注記ヒントは、手順5および6のToPrimitiveの呼び出しでは提供されません。日付オブジェクト以外のすべてのネイティブECMAScriptオブジェクトは、ヒント番号が指定されたかのようにヒントが存在しないことを処理します。 Dateオブジェクトは、hint Stringが指定されたかのように、ヒントが存在しないことを処理します。ホストオブジェクトは、他の何らかの方法でヒントがないことを処理することがあります。

注記2手順7は、論理演算子の代わりに論理演算子を使用して、関係演算子(11.8.5)の比較アルゴリズムの手順3とは異なります。

私の推測では、ポイント7は、誰かがために非常に簡単な説明を提供することができ、前述したように異なる評価/変換によって、いくつかの方法で達成されたが、私は本当に...

をhappenningれているものを把握することはできませんということでしたこの ?


私は、なぜ答えることを試みるために少し良くこのすべてを理解して喜んだ:

[] + {} -> [object Object] 
{} + [] -> 0 

答えて

7
  1. レッツがたToPrimitive(LVAL)ことlprim。
  2. rprimをToPrimitive(rval)にします。

何らヒントをToPrimitiveに提供されていないので:

Oの[[のDefaultValue]]内部メソッドがない ヒントで呼び出された場合ヒント番号であるかのように、それは、振る舞いOが日付 オブジェクト(15.9.6参照)でない場合は、ヒントが 文字列であるかのように動作します。

は、だから、ナンバーヒントを呼び出すのと同じです:

When the [[DefaultValue]] internal method of O is called with hint Number, the following steps are taken: 
1. Let valueOf be the result of calling the [[Get]] internal method of object O with argument "valueOf". 
2. If IsCallable(valueOf) is true then, a. Let val be the result of calling the [[Call]] internal method of valueOf, with O as the this value and an empty argument list. b. If val is a primitive value, return val. 
3. Let toString be the result of calling the [[Get]] internal method of object O with argument "toString". 
4. If IsCallable(toString) is true then, a. Let str be the result of calling the [[Call]] internal method of toString, with O as the this value and an empty argument list. b. If str is a primitive value, return str. 
5. Throw a TypeError exception. 

[].valueOf()の戻り値がない原始的であるので、それは""を返し[].toString()に行きます。

アレイの.toString.join(",")


{} + []

{}ここではオブジェクトとしてではなくとして扱われていないを返しながら、オブジェクトの.toString[object Object]を返す以外はこれと同じで、対象オブジェクトに適用され空のブロック。だから、実行されるコードは次のとおりです。

{} 
+[]; //Same as +[] (Number([])) which is 0 

あいまいさを解決し、{} + []使用から正常な結果を得るには

({}) + []または({} + [])

おかしいコード:

{} ! [] //false 
({}) ! [] //SyntaxError 
+0

は今より理にかなっています。仕様は、かなり入り込むことができますが、今ではいくつかのリードを持っています。ありがとう。 –

+0

@DidierGhysうん、オブジェクトリテラルに注意すると、javascriptはできるだけブロックとしてそれらを扱うことが非常に熱望されています。 – Esailija

+0

私はそれを念頭に置いておきます。 –

関連する問題