0

this #javascript doesn't make sense:

> typeof []
< "object"
> typeof {}
< "object"
> []+1
< "1"
> {}+1
< 1

typeof array [] and object literal {} return "object" as the type but when array plus 1 yields a string of "1" while object literal {} plus 1 yields integer 1. Why?

can someone explain?

Leo Nix
  • 2,085
  • 2
  • 24
  • 37
  • check the solutions in that question, I think they will solve your´s one too – Alejandro Teixeira Muñoz Jun 10 '15 at 14:27
  • 1
    Lots of JavaScript doesn't make sense; get used to it :) – Dave Newton Jun 10 '15 at 14:29
  • [Wat!?](https://www.destroyallsoftware.com/talks/wat) – deceze Jun 10 '15 at 14:32
  • 2
    `{}` is a block, not an object literal. – Felix Kling Jun 10 '15 at 14:35
  • @FelixKling Since a block contains statements does that mean `foo: 'bar'` is a statement? Or if there are a list of key/value pairs separated by commas it's actually a single statement? In the context of an object initializer the spec doesn't reference the `{}` as a block, rather as a syntactic part of the object initializer: http://www.ecma-international.org/ecma-262/5.1/#sec-11.1.5 and specifically states "The production ObjectLiteral : { } is evaluated as follows". I'm curious; it's likely I'm confused as I haven't spent much time w/ the spec. – Dave Newton Jun 10 '15 at 14:40
  • @DaveNewton: Depends on the context. If `{...}` is interpreted as a block, then yes, `foo: 'bar'` is a *LabelledStatement*. http://www.ecma-international.org/ecma-262/5.1/#sec-12.12. A label followed by a string literal. `foo: 'bar', bar: 42` is then a syntax error. – Felix Kling Jun 10 '15 at 14:42
  • @FelixKling But... wouldn't an empty object initializer still be an object, and not a block? `typeof {}` shouldn't be interpreting the `{}` as a block, but as an expression? Oh how I wish I knew stuff :/ – Dave Newton Jun 10 '15 at 14:44
  • 1
    @DaveNewton: Yes, in `typeof {}`, `{}` is an object literal. In `{} + 1` it is a block. My first comment was merely referring to the second case that seemed to create the confusion. It all depends on the context. In an expresion context, `{}` is always going to be an object literal. However, `{} + 1` is ambiguous. – Felix Kling Jun 10 '15 at 14:45
  • @FelixKling Huh. But as soon as you put something in it it gets parsed as an object literal instead, e.g., `a = {foo: "bar"} + 1 >> "[object Object]1"`? – Dave Newton Jun 10 '15 at 14:48
  • 1
    @DaveNewton: No, on the right hand side of an assignment can only be an expression: `a = `. If you type `{foo: "bar"} + 1` you get the same result as with an empty "object". – Felix Kling Jun 10 '15 at 14:49
  • @FelixKling Hrm. Okay; I think I knew less than when I started, but thanks for trying :) – Dave Newton Jun 10 '15 at 14:49
  • 1
    @DaveNewton: To recap again: What `{...}` is interpreted as is independent of what it contains. All that matters is where `{` is located. If it is where only an *expression* can be, then it will be interpreted as an object literal. If it is ambiguous, i.e. both, a block and an object literal would be valid at this position, then it will be interpreted as a block. `{}+1` is ambiguous, hence it is interpreted as an empty block `{}`, followed by an expression statement containing a unary plus `+1`. `typeof {}` is not ambiguous. `typeof` must be followed by an expression. – Felix Kling Jun 10 '15 at 14:52
  • @FelixKing, you should post an answer explaining the various contexts in which `{}` is evaluated as an expression or a block and why the type conversions vary based on context. Seems like you've got it figured out. Would love to see a thorough explanation. – gfullam Jun 10 '15 at 14:53
  • 1
    @gfullam: I and others have: http://stackoverflow.com/q/11939044/218196, http://stackoverflow.com/q/9032856/218196, http://stackoverflow.com/q/25416725/218196, http://stackoverflow.com/q/18510335/218196, http://stackoverflow.com/q/3731802/218196 .... it's just not easy to find. I searched for `[javascript] object literal plus` to get those. – Felix Kling Jun 10 '15 at 14:56
  • @FelixKling I see now (maybe), I guess I'm not sure how `{ foo: 'bar'} + 1` makes it an OI rather than a block w/ a labeled statement if it's still possibly ambiguous. Chrome JS console. – Dave Newton Jun 10 '15 at 15:10
  • @Dave: `{ foo: 'bar'} + 1` is not interpreted as an object literal. I get `1` in Chrome as output. – Felix Kling Jun 10 '15 at 15:12
  • @FelixKling Right; I had an assignment in there that changed the context, you said as much above--sorry, and thanks again :) – Dave Newton Jun 10 '15 at 15:17
  • thanks guys for your very helpful comments. I posted this question on twitter as well and got similar answers. – Leo Nix Jun 10 '15 at 15:34

0 Answers0