16

If you open a JS Console in your browser (in my case Chrome) and type:

{} + []

you will get 0, but when you type

console.log({} + [])

you get [object Object]... any ideas why the result is different? I've always thought that when you type there it always wrap it with console.log?

kuba
  • 1,019
  • 1
  • 18
  • 39

4 Answers4

12

{} can either be an empty block or a empty object literal depending on context.

+ can either be the unary plus operator or the concatination operator depending on context.

The first code example is an empty block it might as well not be there, making the expression the same as +[], meaning "An empty array converted to a number".

You can't have a block as a function argument, so the second code example {} is an object and the code means "Concatinate an object with an array" (implicitly converting both object and array to strings).

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • I just noticed that `{aa: "www"} + []` also returns `0` Does that mean it does treat `{}` always like an object literal and it doesn't matter if it is empty or not as `+[]` will always result in the same? – Nope Oct 11 '17 at 08:56
  • 2
    @Fran — It means it always treats it as a block. – Quentin Oct 11 '17 at 08:58
  • 3
    {aa: "www"} is a probably interpreted as a label – notrota Oct 11 '17 at 08:59
5

When you see {} character at the beginning it is interpreted as a empty block or empty object literal(when you're creating objects).

When you're using an expression or statement, + represent the plus operator, which coerces its operand(in this case it will be []) to a number.

So +[] is the same as Number([]), which evaluates to 0.

The unary plus operator internally use the ToNumber abstract operation.

Read more about Type Conversions and operators.

console.log(Number([]));

With the other words, {} + [] expression is an empty code block followed by an array which will be constraint to a number(Number[]).

In the second example you're providing you just concat an object literal(empty object) to an array. That't why you're receiving [object Object].

Mihai Alexandru-Ionut
  • 47,092
  • 13
  • 101
  • 128
3

Empty object as {} returns "[object Object]" when you call its toString() method. Empty array returns "" when you call its toString() method. Thus, console.log({} + []) will output "[object Object]"

Nicolas P.
  • 581
  • 1
  • 4
  • 15
  • 1
    Why does `console.log({})` output `{}` then? – deceze Oct 11 '17 at 08:37
  • 1
    @deceze Because you are not trying to add two things that can only be added if you do an implicit toString conversion. That means if you only provide one object it can be "dumped". – Mörre Oct 11 '17 at 08:42
  • @Mörre No. If `console.log` always turned everything into a string, it wouldn't output `{}`. The basic premise of this answer is wrong. – deceze Oct 11 '17 at 08:42
  • @deceze Because using just `({})` instead of `({} + [])` doesn't trigger concatenation and it just prints out the object you passed it? – Nope Oct 11 '17 at 08:43
  • @deceze try adding `({}) + []`, it returns `"[object Object]"` – Nicolas P. Oct 11 '17 at 08:43
  • @NicolasP. Yes, because of the difference in context and how it makes Javascript interpret `{}`. Quentin's and Alexandru's answers get it right. – deceze Oct 11 '17 at 08:45
  • @deceze Your response makes no sense. Read what I wrote, please. Obviously console.log doesn't use the `toString` when it dumps an object (lists its contents using special object-dump code), only when it has to concatenate it to another string, for example, try `console.log({foo:1} + 42)`. – Mörre Oct 11 '17 at 08:45
  • @Mörre `console.log` has nothing to do with this. `console.log` just outputs the result of the expression within it. It itself doesn't concatenate anything or coerce anything into a different type. The expression `{} + []` is different inside a `console.log` and outside it. That's the crux of the matter. Not because of what `console.log` does, but because of how Javascript interprets the expression in the different contexts. – deceze Oct 11 '17 at 08:47
  • @Mörre Yes, the `+` does it. But why does the `+` result in `0` in one context and in a string in another? *That's* the issue. – deceze Oct 11 '17 at 08:49
  • @deceze Your question, let me quote: _"Why does console.log({}) output {} then?"_ --- I answered the question you _actually asked_. If it wasn't the question you had - I don't have remote mind reading skills. – Mörre Oct 11 '17 at 08:49
  • @Mörre The original answer stated: *"When you log something in JavaScript, the output is a string representation"* – I replied why `console.log({})` outputs `{}` then, which obviously contradicts that statement. That was the point. – deceze Oct 11 '17 at 08:50
  • @deceze In a way does `console.log()` not have something to do with the difference in results? It doesn't turn everything into a string but I assume it is because it turns it into a function expression causing the difference in results between `{} + []` and `({} + [])` no? – Nope Oct 11 '17 at 08:50
  • @deceze Please read my previous comment. I answered the question that you actually asked. – Mörre Oct 11 '17 at 08:51
  • @Fran But it's not `console.log` per se. – deceze Oct 11 '17 at 08:51
  • @deceze You asked: _"Why does console.log({}) output {} then"_ -- That is the qestion I answered. – Mörre Oct 11 '17 at 08:51
  • @Mörre and that first part wasn't quite right, my bad. Went a bit too fast. – Nicolas P. Oct 11 '17 at 08:51
  • @Mörre We had a bit of an impedence mismatch there, okay. Let's bury that topic. – deceze Oct 11 '17 at 08:52
0

it's because {} is an object notation so whatever you concatenate with {} it will give you an [object Object]. I your case [] is an empty so it just shows an [object Object]. so if you could try the following you will got what you want.

 console.log({} + 5);
 [object Object]5  ///console shows 
      //And
console.log({} + "test");
VM65:1 [object Object]test //console shows
Salman
  • 333
  • 4
  • 18