Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't explain these results [duplicate]

Tags:

javascript

Can someone explain to me why these results?

enter image description here

I know this is not a real problem, but I'm curious to know.

Thanks

like image 979
Majid Laissi Avatar asked Jun 20 '13 18:06

Majid Laissi


2 Answers

This because + is meant to add numbers and strings, it's also the unary operator. It's also because {} is both an empty object and a block statement.

I can explain this.

[] + {}

Both are converted to strings.

[].toString() + {}.toString()

[].toString() is the same as [].join(''), and {}.toString() is '[object Object]', so the first one is [object Object].

The second one is more confusing.

{} + []

The {} here is not interpreted as an object, is interpreted as an empty block. So the code inside is ran. There's nothing inside, so it does nothing, then the next statement is ran: +[]. This converts the array to an int, which first converts it to a string than an it.

{} + [] => +[] => +([].toString()) => 0

If you put the {} in parenthesis, it'd be the same as the first.

({}) + [] => '[object Object]'
like image 113
Rocket Hazmat Avatar answered Oct 06 '22 04:10

Rocket Hazmat


From here, related to this

  1. [] + []

    When using the addition operator, both the left and right operands are converted to primitives first (§11.6.1). As per §9.1, converting an object (in this case an array) to a primitive returns its default value, which for objects with a valid toString() method is the result of calling object.toString() (§8.12.8). For arrays this is the same as calling array.join() ([§15.4.4.2][4]). Joining an empty array results in an empty string, so step #7 of the addition operator returns the concatenation of two empty strings, which is the empty string.

  2. [] + {}

    Similar to [] + [], both operands are converted to primitives first. For "Object objects" (§15.2), this is again the result of calling object.toString(), which for non-null, non-undefined objects is "[object Object]" ([§15.2.4.2][5]).

  3. {} + []

    The {} here is not parsed as an object, but instead as an empty block ([§12.1][6], at least as long as you're not forcing that statement to be an expression, but more about that later). The return value of empty blocks is empty, so the result of that statement is the same as +[]. The unary + operator ([§11.4.6][7]) returns ToNumber(ToPrimitive(operand)). As we already know, ToPrimitive([]) is the empty string, and according to [§9.3.1][8], ToNumber("") is 0.

  4. {} + {}

    Similar to the previous case, the first {} is parsed as a block with empty return value. Again, +{} is the same as ToNumber(ToPrimitive({})), and ToPrimitive({}) is "[object Object]" (see [] + {}). So to get the result of +{}, we have to apply ToNumber on the string "[object Object]". When following the steps from [§9.3.1][9], we get NaN as a result:

    If the grammar cannot interpret the String as an expansion of StringNumericLiteral, then the result of [ToNumber][10] is NaN.

  5. Array(16).join("wat" - 1)

    As per [§15.4.1.1][11] and [§15.4.2.2][12], Array(16) creates a new array with length 16. To get the value of the argument to join, [§11.6.2][13] steps #5 and #6 show that we have to convert both operands to a number using ToNumber. ToNumber(1) is simply 1 ([§9.3][14]), whereas ToNumber("wat") again is NaN as per [§9.3.1][15]. Following step 7 of [§11.6.2][16], [§11.6.3][17] dictates that

    If either operand is NaN, the result is NaN.

    So the argument to Array(16).join is NaN. Following §15.4.4.5 (Array.prototype.join), we have to call ToString on the argument, which is "NaN" ([§9.8.1][18]):

    If m is NaN, return the String "NaN".

    Following step 10 of [§15.4.4.5][19], we get 15 repetitions of the concatenation of "NaN" and the empty string, which equals the result you're seeing. When using "wat" + 1 instead of "wat" - 1 as argument, the addition operator converts 1 to a string instead of converting "wat" to a number, so it effectively calls Array(16).join("wat1").

like image 26
nicosantangelo Avatar answered Oct 06 '22 03:10

nicosantangelo