JS Tip of the Day: Not All Functions Are Constructors

Not All Functions Are Constructors
Version: ES2015+ (new function types)
Level: Intermediate

It used to be that whenever you made a function, that function could also be used as a constructor to make new object instances. This sometimes also made it confusing to know which functions were meant to be used simply as functions and which were to be used as constructors. The convention of always capitalizing the first letter in a constructor function’s name was used to helped make this distinction.

function MyConstructor () {
    // ...
}

function myNormalFunction () {
    // ...
}

With ES2015, the new class syntax came along to help with this problem. Not only can you tell from class that what’s being defined is to be used only to create new object instances, but if you try to call a class constructor as a normal function, you’ll get an error.

class MyClass {
    // ...
}

new MyClass(); // Ok
MyClass(); // TypeError: cannot be invoked without 'new'

Flipping that around, all other new function types added in ES2015 and beyond can only be used as functions and not constructors. They will cause an error if you try to use them with new.

// arrow functions
let arrow = () => {};
new arrow(); // TypeError: not a constructor

// methods (object and class)
let obj = {
    method () {}
};
new obj.method(); // TypeError: not a constructor

// generator functions
function * gen () {}
new gen(); // TypeError: not a constructor

// async functions
async function nsync () {}
new nsync(); // TypeError: not a constructor

The only kinds of functions that can be constructors are:

  • Normal function declarations and expressions
  • class constructor functions
  • Functions created with the Function constructor

More Info: