++[[]][+[]]+[+[]] は “10”
問題
++[[]][+[]]+[+[]] は 10 になる。 なんで!???
確認: ← クリックすると alert(++[[]][+[]]+[+[]]) します。
答え
以下、過程(細かいところは下に補足説明)。
++[[]][+[]]+[+[]] = ++[[]][+[]] + [+[]] = ++[[]][+""] + [+""] = ++[[]][0] + [0] = +([] + 1) + [0] = +("" + 1) + [0] = +("1") + [0] = 1 + [0] = 1 + "0" = "10"
補足
JavaScriptでは、+[] === 0 である。+ 演算子は対象を数値に変換する。+[] === +”” === 0 となる。
[[]] は、空の配列1個([])の配列([[]])である。[[]][0]は配列の最初の要素を取得するので、[]になる。
++[[]][0] が1になるのは、var a = []; ++a; で、a が1になるのと同じ。
++は1加算するので、++[[]][0] == 「(中の空の配列 + 1)を数字にしたもの」 == 「(”” + 1)を数字にしたもの」 == 「”1″ を数字にしたもの」 == 1。
Javascriptでは、空の配列 [] + 1 == “” + 1 == “1” となる。このときの [] は 空の要素を結合した “” になる。
同様に、1 + [0] の [0] は、要素を結合した文字 “0” になる。
最後に number + string = string のように扱われるので、 1 + “0” === “10” 。
+[] の詳細
This is quite a maze, but to do +[], first it is being converted to a string because that’s what + says:
11.4.6 Unary + Operator
The unary + operator converts its operand to Number type.
The production UnaryExpression : + UnaryExpression is evaluated as follows:
1. Let expr be the result of evaluating UnaryExpression.
2. Return ToNumber(GetValue(expr)).ToNumber() says:
Object
Apply the following steps:
1. Let primValue be ToPrimitive(input argument, hint String).
2. Return ToString(primValue).ToPrimitive() says:
Object
Return a default value for the Object. The default value of an object is retrieved by calling the [[DefaultValue]] internal method of the object, passing the optional hint PreferredType. The behaviour of the [[DefaultValue]] internal method is defined by this specification for all native ECMAScript objects in 8.12.8.
[[DefaultValue]] says:
8.12.8 [[DefaultValue]] (hint)
When the [[DefaultValue]] internal method of O is called with hint String, the following steps are taken:
1. Let toString be the result of calling the [[Get]] internal method of object O with argument “toString”.
2.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.The .toString of an array says:
15.4.4.2 Array.prototype.toString ( )
When the toString method is called, the following steps are taken:
1. Let array be the result of calling ToObject on the this value.
2. Let func be the result of calling the [[Get]] internal method of array with argument “join”.
3. If IsCallable(func) is false, then let func be the standard built-in method Object.prototype.toString (15.2.4.2).
4. Return the result of calling the [[Call]] internal method of func providing array as the this value and an empty arguments list.So +[] comes down to +””, because [].join() === “”.
Again, the + is defined as:
11.4.6 Unary + Operator
The unary + operator converts its operand to Number type.
The production UnaryExpression : + UnaryExpression is evaluated as follows:
1. Let expr be the result of evaluating UnaryExpression.
2. Return ToNumber(GetValue(expr)).ToNumber is defined for “” as:
The MV of StringNumericLiteral ::: [empty] is 0.
So +”” === 0, and thus +[] === 0.
参考
http://stackoverflow.com/questions/7202157/can-you-explain-why-10
コメント