Search code examples
javascriptfunctionobjectconstructor

How can a function know whether it has been invoked as a constructor (using the `new` keyword)?


I've noticed that some functions can only be called with the new prefix. When called without it, an error is thrown. Below is an example of how the console reacted when the Image was called in different ways.

console.log(new Image());    // OK
console.log(Image());        // TypeError

This is very different from user-written functions like the one below:

function Foo() {
  this.identity = 'Bar';
}

The function Foo can be called two ways, new Foo() and Foo(). This is very different from the Image function.

The behavior of the Image function is very different from ordinary constructor functions. How is this possible? Is this why the new prefix must be used with Image? And more importantly can this type of function be recreated?


Solution

  • I think this is the logic you're looking for that reproduces the exception when the new keyword isn't used to create an instance of Foo:

    function Foo() {
        if (!(this instanceof arguments.callee)) 
            throw new TypeError("DOM object constructor cannot be called as a function.");
    
        this.identity = 'Bar';
    }
    

    According to some comments in this post, instead of arguments.callee you'd have to use the function name Foo if you are in strict mode:

    function Foo() {
        if (!(this instanceof Foo)) 
            throw new TypeError("DOM object constructor cannot be called as a function.");
    
        this.identity = 'Bar';
    }
    

    See a DEMO here that illustrates the situation.