Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the curly brackets object notation valid in any expression?

I'm currently analyzing the Javascript language a bit. It looks like you could group at lot of the concepts into a base type called expression. Even function arguments and definitions fit into that group, as well as strings, numbers and mathematical expressions. The only illogical exception was the curly bracket object notation in a nonsense alike context.

As functions consist of several expressions the following code is valid:

function valid(){
    /\W/;
    "ahll";
    var alpha;
    alpha;
    alpha={"first": 90, "second": 80};
    alpha;
    0, {"first": 90, "second": 80};
    [1,2,3];
    alpha;
    2+3;
    new RegExp("/\W/");
    return true;
}

By intention the following code should be valid too, but gets a "missing ; before statement" syntax error for the second line:

function invalid(){
    {"first": 90, "second": 80};
    return true;
}

The curly bracket object notation is accepted in every other case where expressions are accepted, except for these cases where a curly bracket code block would be allowed too.

Is the syntax error mentioned above caused by the implementation or the specification of javascript?

Is there a more precise name for such nonsense expression?

like image 360
schwer Avatar asked Oct 02 '22 06:10

schwer


2 Answers

What you are viewing as an object, in the last example, is actually a block:

From the MDN:

A block statement is used to group zero or more statements. The block is delimited by a pair of curly brackets.

So, basically, when you start the curly braces, it understands it to be a block, and gives the error:

Uncaught SyntaxError: Unexpected token : 

Because it does not like those colons (:) inside of a block where it expects statements (var a = 2, etc.). It assumes that whatever follows the curly brace must be a set of statements, and hence is surprised to see the colon, and in confusion throws an error. Note that "first": 90 is not a valid statement.

Then why does 0, {"first": 90, "second": 80}; pass ?

Because after seeing the first expression (0), and then the comma operator, it expects to see another value of a similar type (i.e. another expression). And thus it treats the second object {"first": 90, "second": 80} as an object (which is also an expression) instead of a block.

To further simplify, try {"first": 90, "second": 80}, 0. Notice, it gives a SyntaxError exactly the same as the previous one. Because, once it sees the {, it treats the following as a block, and again complains for the colon (:).

How do I avoid this?

By making it a part of another expression, like:

( {1:2} ) // a block doesn't come inside parentheses
var a = {1 : 2}; // a block can't be the RHS
myFunc( { 1 : 5 } ) // a block can't be a function argument

Hope it helps!

like image 116
Gaurang Tandon Avatar answered Oct 05 '22 13:10

Gaurang Tandon


Is the syntax error mentioned above caused by the implementation or the specification of javascript?

By the spec.

Is there a more precise name for such nonsense expression

You're looking for the term Expression Statement. As you say, Object literals are expressions (even primary expressions), just as most other things are. They can appear in many contexts, like function arguments, operands of an operator or inside brackets.

However, a function body - code - does not consist of expressions, it does consist of statements. That means things like if-statements, loop statements or plain blocks. Or "expression statements", which are nothing but an expression to be evaluated (and with side effects, they mostly are not "nonsense").

However, the spec mandates:

ExpressionStatement: [lookahead ∉ {{, function}] Expression ;

NOTE: An ExpressionStatement cannot start with an opening curly brace because that might make it ambiguous with a Block. Also, an ExpressionStatement cannot start with the function keyword because that might make it ambiguous with a FunctionDeclaration.

like image 24
Bergi Avatar answered Oct 05 '22 13:10

Bergi