Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Array + Array equals empty string?

Tags:

javascript

I've seen this pretty funny screencast yesterday about some oddities in languages like Ruby and Javascript and the guy shows that:

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

not very obvious...

I've decided to go to the ECMAscript language specification to get more info. I've started with the + operator implementation (p.75) which says:

11.6.1 The Addition operator ( + )

The addition operator either performs string concatenation or numeric addition.
The production AdditiveExpression : AdditiveExpression + MultiplicativeExpression is evaluated as follows:
1. Let lref be the result of evaluating AdditiveExpression.
2. Let lval be GetValue(lref).
3. Let rref be the result of evaluating MultiplicativeExpression.
4. Let rval be GetValue(rref) .
5. Let lprim be ToPrimitive(lval).
6. Let rprim be ToPrimitive(rval).
7. If Type(lprim) is String or Type(rprim) is String, then
a. Return the String that is the result of concatenating ToString(lprim) followed by ToString(rprim)
8. Return the result of applying the addition operation to ToNumber(lprim) and ToNumber(rprim). See the Note below 11.6.3.

NOTE1 No hint is provided in the calls to ToPrimitive in steps 5 and 6. All native ECMAScript objects except Date objects handle the absence of a hint as if the hint Number were given; Date objects handle the absence of a hint as if the hint String were given. Host objects may handle the absence of a hint in some other manner.

NOTE 2 Step 7 differs from step 3 of the comparison algorithm for the relational operators (11.8.5), by using the logical-or operation instead of the logical-and operation.

My guess was that the point 7 was reached in some way through different evaluations/conversions as described before but I cannot figure out what is really happenning...

Can someone provide a much straightforward explanation for this ?


I'm willing to understand all this a bit better in order to try to answer why:

[] + {} -> [object Object]
{} + [] -> 0
like image 447
Didier Ghys Avatar asked Jan 21 '12 08:01

Didier Ghys


People also ask

Why is empty array not equal to empty array?

Because they are not same object, different object never identical equal, so the result is false . Save this answer.

What does an empty array equal to?

An empty array will have 0 elements inside of it.

Why is empty array true?

Because Array is type of object , the fact that an empty Array is conversed to true is correct.

What does an empty string array return?

If the array has a length of zero, then it does not contain any element. To return an empty array from a function, we can create a new array with a zero size. In the example below, we create a function returnEmptyArray() that returns an array of int . We return new int[0] that is an empty array of int .20-Jan-2021.


1 Answers

  1. Let lprim be ToPrimitive(lval).
  2. Let rprim be ToPrimitive(rval).

Since no hint is provided to ToPrimitive:

When the [[DefaultValue]] internal method of O is called with no hint, then it behaves as if the hint were Number, unless O is a Date object (see 15.9.6), in which case it behaves as if the hint were String.

So it's same as calling with a Number hint:

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.

Since the return value of [].valueOf() is not a primitive, it goes to [].toString() which returns "".

This same applies for object objects, except the .toString of an object returns [object Object] while .toString of an array returns .join(",")


{} + []

The {} is not treated as an object here but as an empty block. So the code that runs is:

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

To resolve the ambiguity and get normal result from {} + [] use

({}) + [] or ({} + [])

Funny code:

{} ! [] //false
({}) ! [] //SyntaxError
like image 178
Esailija Avatar answered Oct 05 '22 00:10

Esailija