What Do Braces Do In Javascript?
Solution 1:
as object literals
var a = {field1:value1, field2:value2}
as function bodies
functionfunc() {
// do something
}
var f = function() { /* do something */ };
varf = ()=>{}; // ditto
where the first item in the statement is an object literal
// {}.toString(); // syntax error, first brace of statement = code block
({}).toString(); // correct
as destructured assignment
var obj = {a:1, b:2, c:3};
var {a:x, c:y} = obj; // assign obj.a to x, and obj.c to y
({a:x, c:y} = obj); // ditto
Note - this has a lot of forms so I won't cover them all, full info found here (thanks RobG)
how this is interpreted
You can assume that all your JS code is inside some {}
block. So the start of your code is immediately after a {
always.
Wherever a value is expected, {}
does not mean a function body. At the start of a statement this is ambiguous because you can have anonymous code blocks like so:
var x = 1;
{
var x = x+2;
// x = 3
}
// x = 3 (!)
This is archaic from C-style syntax where this would influence scope, but in testing this in JS it doesn't seem to have that effect, so for all intents it's rather useless syntax except to identify a code block. If you wanted such behavior you'd need to do this:
var x = 1;
(()=>{
var x = x+2;
// x = 3
})()
// x = 1
If we need an object first in some statement, we need to clarify to JS that we want a value. This is why we use ({})
instead of {}
, because the former is unambiguously an object literal inside parens.
a simpler explanation
Rather than examine when {}
is parsed as a value, let's look at when it isn't. There are two cases in general where we don't treat {}
as an object literal: as a function body or as a statement group (my own term).
Consider the general control statements - if
, for
, while
, with
etc. These can all* be used in a way that completely avoids {}
. In this respect {}
should be thought of as statement groups hence the term.
if (x) x++; else x--;if (x) {x++;} else {x--;}
{if (x) {x++;} else {x--;}}
*note: switch
is an exception, switch(1);
gives an error SyntaxError: missing { before switch body
Using this rule it then makes sense why we must use ()
to denote an object literal if it's the start of a statement - we can't start a statement in ()
, so you can't start a statement group there either, leaving only one option (object literal or related syntax).
This leaves function bodies.
function bodies
First, consider a function declaration statement:
function f () {}
It doesn't need a semicolon (;
). This means the entire thing is a single statement. This explains why the following gives a syntax error in the first form but not the second:
function(){return1;}(); // error: function statement requires namevar x = function(){return1;}(); // fine
This is because the first is parsed as a statement, and a function declaration statement cannot be anonymous. However the second is in a value context and is treated as such. The situation is identical as with object literals, if it could be a statement it cannot be a value, but if we're already knee deep in value land, it has to be a value.
The =>
notation is, with one exception, parsed identically to function
. The ()=>{}
form is identical but in practice differs because this type of function cannot have a this
object - it cannot be an object method (doesn't make much sense to) and it cannot construct new objects (it has no prototype), and other quirks as a result. otherwise it's straightforward to see how it's the same as function(){}
.
()=>...
however is a little different. It's treated as ()=>{return ...}
. But, without the explicit }
to finish the return statement, the syntax greedily captures the largest expression that would parse as such (not necessarily work). Case in point:
()=>1; // statement; = function that returns "1"()=>1(); // statement; = function that returns "1()"
(()=>1()); // TypeError: 1 is not a function
(()=>1)(); // what was intended in above (you'd hope)
Post a Comment for "What Do Braces Do In Javascript?"