1

I recently read the MDN documentation on the new operator, and I was struck by the concise description of what it does:

When the code new Foo(...) is executed, the following things happen:

  1. A new object is created, inheriting from Foo.prototype.
  2. The constructor function Foo is called with the specified arguments and this bound to the newly created object. new Foo is equivalent to new Foo(), i.e. if no argument list is specified, Foo is called without arguments.
  3. The object returned by the constructor function becomes the result of the whole new expression. If the constructor function doesn't explicitly return an object, the object created in step 1 is used instead. (Normally constructors don't return a value, but they can choose to do so if they want to override the normal object creation process.)

It seems like none of those things are privileged operations, so is it possible to completely recreate the action of new with other language constructs?

Note that I don't count Reflect.construct since the very definition of it is that it "acts like the new operator as a function".

1
  • 1
    Notice that since ES6 you must use Reflect.construct, the above description is from ES5. A few builtins as well as constructors defined using class syntax do distinguish between being invoked as a constructor and being invoked like a method.
    – Bergi
    Commented Oct 10, 2016 at 16:31

1 Answer 1

3

This function pretty much recreates Reflect.construct, and thus new (with the exception of construct's last argument, which has no equivalent when using the new operator:

function fauxNew (constructor, args) {

    // allocate a new object and set the prototype
    var newObject = Object.create(constructor.prototype)

    // call the constructor with "this" bound to the new object
    var retVal = constructor.apply(newObject, args || [])

    // if the constructor returned an object, return it; 
    // otherwise return the new object
    var constructorReturnedAnObject = 
        !!retVal && ["object", "function"].indexOf(typeof retVal) !== -1
    return constructorReturnedAnObject? retVal : newObject
}

Here is the same code presented alongside some test cases.

1
  • 1
    Don't trust typeof when detecting an object. It may return strange things for non-callable non-standard exotic objects, e.g. "unknown". Object(retVal) === retVal is more reliable.
    – Oriol
    Commented Aug 25, 2016 at 13:51

Not the answer you're looking for? Browse other questions tagged or ask your own question.