0

So an object like

{bar: 2}

will return the object itself, which is

{bar: 2}

But if I try

foo: {bar: 2}

Then I will get 2 instead

What is the : operator does here exactly? I can't find it in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators...

7
  • 5
    You're creating a labeled statement. And it's not an "operator". Commented Jun 20, 2018 at 14:06
  • @Pointy a labeled statement? But what does a labeled statement return a different result? Commented Jun 20, 2018 at 14:08
  • 2
    You're confusing the behavior of the console API with what the language actually does. Statements don't "return results" at all. Commented Jun 20, 2018 at 14:09
  • @Pointy - In specification terms, they actually do, which is part of why consoles show them. We just can't access their result values. Commented Jun 20, 2018 at 14:10
  • @T.J.Crowder yes that's true, though I've never really understood the point of that dark corner of the language spec. One of many. Commented Jun 20, 2018 at 14:16

2 Answers 2

7

First of all, absent other context:

{bar: 2}

does not create an object. It's a block statement with a single statement inside, and that statement has a label:

{
  bar: // the label
  2    // the expression statement
}

The text {bar: 2} is only an object when it appears in the context of an expression, like this:

foo({bar: 2}); // a function call to "foo", passing an object

Otherwise, a statement that begins with { is always interpreted as a block.

The statement

foo: {bar: 2}

is basically the same. Here, there's a label (foo:) outside the block, and a label (bar:) inside.

When you're trying code via a browser console, or Node, things get weird because the console itself has behavior intended to help with debugging but which is also different from language semantics in some cases. JavaScript is not directly a "REPL-friendly" syntax, so the console mechanism has to be clever.

Sign up to request clarification or add additional context in comments.

Comments

5

JavaScript doesn't have a : operator. But : is used in various syntax productions.

Within an object initializer's property initializer, the : separates the property name from the property value. That's what you're using in your first example.

At statement level, not in an object initializer, a name followed by : is a statement label. That's what your foo: {bar: 2} example is. Labels are mostly used for directed break and continue.

(: is also used in the conditional operator, condition ? a :b.)

So then the question is: Why do you see {bar: 2} in the console in the first example, and 2 in the console in the second example?

The answer is that it's special behavior of the console, in two different ways:

  1. When you type {bar: 2} into the console, it treats that as an expression, and so it sees it as an object initializer and creates, then logs, the object. But if you had {bar: 2} at the top level of script code, it wouldn't be an expression, it would be a block with a labelled statement in it. Treating it as an expression is console-specific.

  2. When you type foo: {bar: 2} into the console, it correctly identifies that a labelled statement — two of them, in fact: foo: ... and bar: 2. The {} are a block, not an object initializer, and so the inner bar: is a label.

    So why 2 then? Because it's showing you the result of that code, which isn't available to us syntactically, but is defined by the specification. The result of a block is the last value evaluated within that block, and the labels are transparent. The last value in the {bar: 2} block is 2, so the block's value is 2, so that's what it shows. But again, this is not something we can directly observe in code, it's console behavior.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.