How to Omit Parentheses When Creating an Object Using the "New" Operator

Can we omit parentheses when creating an object using the new operator?

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 the new 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)

When are parentheses and new keywords required when creating new objects in JavaScript?

Given: new Date()

This is the "standard" way to create a new object from a constructor-function1; it returns a new Date object representing the current time.

Given: Date()

JavaScript defines the Date function to operate like this when not called as a constructor (ie. with new). It returns a different value - a string and not a Date object - than new Date(). See Why we can't call methods of Date() class without new operator.

User-code can also check the value of this inside a constructor-function to determine if new was used, although this is only done relatively infrequently. See How to detect if a function is called as constructor?

Given: new Date

When using new the parenthesis are optional if there are no arguments. This is just an additional syntax form that most people don't use - it is equivalent to new Date() if the expression is terminated. See Can we omit parentheses when creating an object using the "new" operator?

Given: Date

This evaluates the expression to the constructor-function (which is just a function-object!2) without invoking it or creating a new instance. This is why the result shows a "function" - it is the constructor-function.


1 I use the term constructor-function to emphasis the point that a constructor is only a function that [also] supports new; it is technically sufficient to call it a constructor.

2 Likewise, it is important to understand that function[-objects]s in JavaScript are first-class citizens and thus just values themselves; like any object. In the last example the assignment of the object/value occurred without performing any action (ie. function invocation) upon the object itself.

Can we create an object without parentheses?

new keyword is used to allocate memory for the specific type, which is followed by new keyword.

MyClass obj = new MyClass();

Above line will create an object (allocate memory) for MyClass and initialize member variable by invoking default constructor.

But, below line of code will only allocate memory and initialize each element of array with default value null.

MyClass[][] objMatrix = new MyClass[5][10];

So, we are just declaring an array of size 5x10(allocating memory), but each element in array need some object reference (since, currently they have null reference). So, for that reason, you need to initialize each objMatrix array element by creating object of MyClass and assigning them to each element.

objMatrix[0][0] = new MyClass();

Constructor invocation without parentheses

According to the MDN docs:

[...] "new foo" is equivalent to "new foo()", i.e. if no argument list is
specified, "foo" is called without arguments.

Parentheses after new function optional?

A similar questions was asked here: new MyClass() vs. new MyClass. The complete and accepted answer by Daniel Vassallo:

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 the new 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)

Use of operator()() without parentheses?

I think you need overload operator -> and/or * (this is how smart pointers are done):

template <typename Object>
struct ObjectWrapper {
ObjectWrapper(Object& o)
: object_(&o)
{
LOG();
}

Object* operator->() const
{
LOG();
return object_;
}

Object& operator*() const
{
LOG();
return *object_;
}

Object* object_;
};

int main()
{
A a;
ObjectWrapper<A> obj { a };
obj->Func();
(*obj).Func();
}

https://godbolt.org/z/ErEbxWE4P

Do the parentheses after the type name make a difference with new?

Let's get pedantic, because there are differences that can actually affect your code's behavior. Much of the following is taken from comments made to an "Old New Thing" article.

Sometimes the memory returned by the new operator will be initialized, and sometimes it won't depending on whether the type you're newing up is a POD (plain old data), or if it's a class that contains POD members and is using a compiler-generated default constructor.

  • In C++1998 there are 2 types of initialization: zero and default
  • In C++2003 a 3rd type of initialization, value initialization was added.

Assume:

struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m

In a C++98 compiler, the following should occur:

  • new A - indeterminate value
  • new A() - zero-initialize

  • new B - default construct (B::m is uninitialized)

  • new B() - default construct (B::m is uninitialized)

  • new C - default construct (C::m is zero-initialized)

  • new C() - default construct (C::m is zero-initialized)

In a C++03 conformant compiler, things should work like so:

  • new A - indeterminate value
  • new A() - value-initialize A, which is zero-initialization since it's a POD.

  • new B - default-initializes (leaves B::m uninitialized)

  • new B() - value-initializes B which zero-initializes all fields since its default ctor is compiler generated as opposed to user-defined.

  • new C - default-initializes C, which calls the default ctor.

  • new C() - value-initializes C, which calls the default ctor.

So in all versions of C++ there's a difference between new A and new A() because A is a POD.

And there's a difference in behavior between C++98 and C++03 for the case new B().

This is one of the dusty corners of C++ that can drive you crazy. When constructing an object, sometimes you want/need the parens, sometimes you absolutely cannot have them, and sometimes it doesn't matter.

Why would you invoke new Date without parentheses?

You can invoke constructors in JS w/o the parenthesis if no arguments are to be passed, the effect is the same.

new Date() vs new Date the same.

However, it makes a difference when you want to call a method on the resulting object:

new Date().getTime() works but new Date.getTime() would not because in the latter case the interpreter assumes getTime is a method of the Date type which isn't the case, getTime is an instance method. To overcome this you can wrap parenthesis around the constructor call to tell the interpreter that it is an expression:

(new Date).getTime()

This way first the expression is evaluated and getTime is called on the result which is an instance of Date.

Invoking a function without parentheses

There are several different ways to call a function without parentheses.

Let's assume you have this function defined:

function greet() {
console.log('hello');
}

Then here follow some ways to call greet without parentheses:

1. As Constructor

With new you can invoke a function without parentheses:

new greet; // parentheses are optional in this construct.

From MDN on the new oprator:

Syntax

new constructor[([arguments])]

2. As toString or valueOf Implementation

toString and valueOf are special methods: they get called implicitly when a conversion is necessary:

var obj = {
toString: function() {
return 'hello';
}
}

'' + obj; // concatenation forces cast to string and call to toString.

You could (ab)use this pattern to call greet without parentheses:

'' + { toString: greet };

Or with valueOf:

+{ valueOf: greet };

valueOf and toString are in fact called from the @@toPrimitive method (since ES6), and so you can also implement that method:

+{ [Symbol.toPrimitive]: greet }
"" + { [Symbol.toPrimitive]: greet }

2.b Overriding valueOf in Function Prototype

You could take the previous idea to override the valueOf method on the Function prototype:

Function.prototype.valueOf = function() {
this.call(this);
// Optional improvement: avoid `NaN` issues when used in expressions.
return 0;
};

Once you have done that, you can write:

+greet;

And although there are parentheses involved down the line, the actual triggering invocation has no parentheses. See more about this in the blog "Calling methods in JavaScript, without really calling them"

3. As Generator

You could define a generator function (with *), which returns an iterator. You can call it using the spread syntax or with the for...of syntax.

First we need a generator variant of the original greet function:

function* greet_gen() {
console.log('hello');
}

And then we call it without parentheses by defining the @@iterator method:

[...{ [Symbol.iterator]: greet_gen }];

Normally generators would have a yield keyword somewhere, but it is not needed for the function to get called.

The last statement invokes the function, but that could also be done with destructuring:

[,] = { [Symbol.iterator]: greet_gen };

or a for ... of construct, but it has parentheses of its own:

for ({} of { [Symbol.iterator]: greet_gen });

Note that you can do the above with the original greet function as well, but it will trigger an exception in the process, after greet has been executed (tested on FF and Chrome). You could manage the exception with a try...catch block.

4. As Getter

@jehna1 has a full answer on this, so give him credit. Here is a way to call a function parentheses-less on the global scope, avoiding the deprecated __defineGetter__ method. It uses Object.defineProperty instead.

We need to create a variant of the original greet function for this:

Object.defineProperty(window, 'greet_get', { get: greet });

And then:

greet_get;

Replace window with whatever your global object is.

You could call the original greet function without leaving a trace on the global object like this:

Object.defineProperty({}, 'greet', { get: greet }).greet;

But one could argue we do have parentheses here (although they are not involved in the actual invocation).

5. As Tag Function

Since ES6 you can call a function passing it a template literal with this syntax:

greet``;

See "Tagged Template Literals".

6. As Proxy Handler

Since ES6, you can define a proxy:

var proxy = new Proxy({}, { get: greet } );

And then reading any property value will invoke greet:

proxy._; // even if property not defined, it still triggers greet

There are many variations of this. One more example:

var proxy = new Proxy({}, { has: greet } );

1 in proxy; // triggers greet

7. As instance checker

The instanceof operator executes the @@hasInstance method on the second operand, when defined:

1 instanceof { [Symbol.hasInstance]: greet } // triggers greet

new operator with parentheses ( , ) instead of brackets [ , ]

GLfloat is an OpenGL alias for float (i.e., typedef float GLfloat;). Consequently the code:

GLfloat* points = new GLfloat(1024);

Is equivalent to:

float* points = new float(1024);

Which allocates a floating point number and initializes it to 1024.0 and assigns its address to pointer points.



Related Topics



Leave a reply



Submit