Can we omit parentheses when creating an object using the "new" operator?
Solution 1:
Quoting David Flanagan1:
As a special case, for the
new
operator only, JavaScript simplifies the grammar by allowing the parenthesis to be omitted if there are no arguments in the function call. Here are some examples using thenew
operator:o = new Object; // Optional parenthesis omitted here d = new Date(); ...
Personally, I always use the parenthesis, even when the constructor takes no arguments.
In addition, JSLint may hurt your feelings if you omit the parenthesis. It reports Missing '()' invoking a constructor
, and there doesn't seem to be an option for the tool to tolerate parenthesis omission.
1 David Flanagan: JavaScript the Definitive Guide: 4th Edition (page 75)
Solution 2:
There are differences between the two:
-
new Date().toString()
works perfectly and returns the current date -
new Date.toString()
throws "TypeError: Date.toString is not a constructor"
It happens because new Date()
and new Date
have different precedence. According to MDN the part of JavaScript operator precedence table we are interested in looks like:
Precedence | Operator type | Associativity | Operators |
---|---|---|---|
18 | Member Access Computed Member Access new (with argument list) |
left-to-right left-to-right n/a |
… . … … [ … ] new … ( … )
|
17 | Function Call new (without argument list) |
left-to-right right-to-left |
… ( … ) new …
|
From this table follows that:
-
new Foo()
has higher precedence thannew Foo
new Foo()
has the same precedence as.
operatornew Foo
has one level lower precedence than the.
operatornew Date().toString()
works perfectly because it evaluates as(new Date()).toString()
new Date.toString()
throws "TypeError: Date.toString is not a constructor" because.
has higher precedence thannew Date
(and higher then "Function Call") and the expression evaluates as(new (Date.toString))()
The same logic can be applied to
… [ … ]
operator. -
new Foo
has right-to-left associativity and fornew Foo()
"associativity" isn't applicable. I think in practice it doesn't make any difference. For additional information see this SO question
Is one preferred over the other?
Knowing all that, it can be assumed that new Foo()
is preferred.
Solution 3:
If you do not have arguments to pass, the parentheses are optional. Omitting them is just syntactic sugar.