Summary: prototypes as classes

Brendan Eich brendan at
Tue Jun 28 17:55:23 PDT 2011

On Jun 28, 2011, at 5:45 PM, Axel Rauschmayer wrote:

>> But before you've created an instance, it is pretty handy to have the constructor bound to a name so you can get to it. I don't think making the named object be the constructor means that they're *more* important, just that you generally have to go through them *first* to get to an instance. They get the name because they're the entrypoint.
> It depends on how you view instance creation:
> Prototypes-as-classes: new C() means:

If there are arguments in between the ( and ), they are passed to o.constructor.

> (1) Create an instance o whose prototype is C.
> (2) Initialize the new instance via o.constructor().

What if o.constructor returns another object than o? See below

> Constructor functions: new C() means:
> (1) Create an instance o whose prototype is C.prototype.
> (2) Initialize it via the body of the constructor function (with |this| set up properly).

Step (2) could be exactly the same as the previous step (2), modulo the forgotten feature which is needed in both cases:

For a function C in JS today, the return value if an object trumps the new instance (and engines actually avoid creating a new instance if it isn't needed for this reason). So there's more to it than this two-step procedure.

> Thus:
> - Prototypes-as-classes: step (1) determines the name of the class (which – to me – makes more sense for instanceof and subclassing)
> - Constructor functions: step (2) determines the name of the class.

I don't see how the step # determines the name of the class. That's backward.

Rather, the two different choices of value bound to the name of the abstraction (prototype vs. constructor) determine the steps.

The prototypes-as-classes approach makes new C(a,b) invoke C.constructor(a, b) with extra rules for object return value, which is a complexity. Especially for abstractions that want to be callable without 'new' to construct a new instance (Array, e.g.).

Intuitions vary. There's nothing magically simpler about either approach. The |this| binding for the constructor invocation can be done in exactly the same way in both cases, but you left out the return value substitution feature.


More information about the es-discuss mailing list