Reputation: 1352
Consider a class defined as:
class Foo { static bar() { return this; } }
I can construct an instance with new (Foo.bar())()
.
But new Foo.bar()()
results in an Uncaught TypeError: Foo.bar is not a constructor
.
Why are those extra parentheses necessary?
Upvotes: 2
Views: 94
Reputation: 5195
new Foo.bar()()
is identical to (new Foo.bar())()
.
Looking at the MDN page for operator precedence, new
and a function call are in the same group. In the spec, the handling of new
can be somewhat confusing. However, new
will be done first.
A nice tool to check, how a specific snippet is being parsed, is https://astexplorer.net/ - it allows you to look at the AST which is the result of parsing.
The error message you get then comes from Foo.bar
being a class method, which don't have [[Construct]], and cannot be used with new
.
As a tip: when it is slightly unclear, how an expression will be parsed, then adding explicit braces often improves readability, even when they may not be necessary.
Upvotes: 2
Reputation: 136
Ex.
(function(){console.log("foo")}())
!function(){console.log("foo")}()
+function(){console.log("foo")}()
All these forces parser to see function(){console.log("foo")}()
side of it as complete expression so it can call immediately.
new (Foo.bar())()
works.When you use new (Foo.bar())()
in first parentheses returns this
which is Foo
itself. Because bar
method is returning Foo
. After second parentheses()
calls it(Foo) and then new
is creates a new instance of Foo
. Basically you are writing new Foo()
with using IIEF.
new Foo.bar()()
throws error.When JS parser sees the expression new Foo.bar()
it is immediately try creates an instance if Foo.bar
and Foo.bar
is not a constructor. After that JS throws that error.
But if parser sees ()
it could throw another error that Uncaught SyntaxError: Unexpected token ')'
. Because JS can not understand the what is left from that line, ()
.
Difference between
new Foo.bar()()
and new (Foo.bar())()
same as
function(){console.log("foo")}()
and (function(){console.log("foo")})()
it throws different error and stop parsing, because Foo.bar
is not a constructor to call.
I hope it helps.
Some links to understand. What does the exclamation mark do before the function?
Upvotes: -1