Can we omit parentheses when creating an object using the “new” operator?
I have seen objects being created this way:
const obj = new Foo;
But I thought that the parentheses are not optional when creating an object:
const obj = new Foo();
Is the former way of creating objects valid and defined in the ECMAScript standard? Are there any differences between the former way of creating objects and the later? Is one preferred over the other?
Quoting David Flanagan1:
As a special case, for the
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.
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
╔════════════╦═════════════════════════════╦═══════════════╦═════════════╗ ║ Precedence ║ Operator type ║ Associativity ║ Operators ║ ╠════════════╬═════════════════════════════╬═══════════════╬═════════════╣ ║ 18 ║ Member Access ║ left-to-right ║ … . … ║ ║ ║ Computed Member Access ║ left-to-right ║ … [ … ] ║ ║ ║ new (with argument list) ║ n/a ║ new … ( … ) ║ ╠════════════╬═════════════════════════════╬═══════════════╬═════════════╣ ║ 17 ║ Function Call ║ left-to-right ║ … ( … ) ║ ║ ║ new (without argument list) ║ right-to-left ║ new … ║ ╚════════════╩═════════════════════════════╩═══════════════╩═════════════╝
From this table follows that:
new Foo()has higher precedence than
new Foo()has the same precedence as
new Foohas one level lower precedence than the
new Date().toString()works perfectly because it evaluates as
new Date.toString()throws “TypeError: Date.toString is not a constructor” because
.has higher precedence than
new Date(and higher then “Function Call”) and the expression evaluates as
The same logic can be applied to
… [ … ]operator.
new Foohas right-to-left associativity and for
new 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.
I don’t think there is any difference when you are using the “new” operator. Be careful about getting into this habit, as these two lines of code are NOT the same:
var someVar = myFunc; // this assigns the function myFunc to someVar var someOtherVar = myFunc(); // this executes myFunc and assigns the returned value to someOtherVar
If you do not have arguments to pass, the parentheses are optional. Omitting them is just syntactic sugar.
Here’s the part of the ES6 spec that defines how the two variants operate. The no-parentheses variant passes an empty argument list.
Interestingly, the two forms have different grammatical meanings. This comes up when you try to access a member of the result.
new Array.length // fails because Array.length is the number 1, not a constructor new Array().length // 0
There’s no difference between the two.