13.2.2 [[Construct]], constructor, and [[Class]] (was __proto__)

liorean liorean at gmail.com
Sun Sep 23 12:56:07 PDT 2007

On 23/09/2007, Garrett Smith <dhtmlkitchen at gmail.com> wrote:
> Function objects get a non-enumerable constructor.
> function F(){};
> F.constructor === Function; // true
> F.prototype.hasOwnProperty('constructor'); //true
> F.prototype.propertyIsEnumerable("constructor"); // false.

Of course.

> Object instances don't, unless it's a prototype object created by [[construct]]
> (new F).constructor === F.constructor; // true. Undesirable

Wrong, it's false.
    (new F).constructor === F.constructor; // => false
    (new F).constructor === F.prototype.constructor; // => true

> This works fine for shallow inheritance
> Objects don't get a constructor

In what way do you mean they don't? Their constructor is the Object
object, as you show next:

> ({}).constructor === Object.prototype.constructor; // True.

> > On 23/09/2007, Garrett Smith <dhtmlkitchen at gmail.com> wrote:
> > > 1. The constructor property should be on the object instance *created*
> > > by the function.

> On 9/23/07, liorean <liorean at gmail.com> wrote:
> > That argument I agree with. It should be on the instance and not the prototype.

On 23/09/2007, Garrett Smith <dhtmlkitchen at gmail.com> wrote:
> Which is different from the way built ins work, but seems OK.

Well, at least if you want to make sense out of the prototypal
inheritance scheme. The built ins are all single level IIRC,k and
don't need to set up their prototype relationship in user code. A
prototype system that didn't just clobber the old prototype when
setting up prototype chains maybe could have done it better. But that
won't happen in ECMAScript.

> > On 23/09/2007, Garrett Smith <dhtmlkitchen at gmail.com> wrote:
> > > 2. (new function(){}).constructor should be Function.

> On 9/23/07, liorean <liorean at gmail.com> wrote:
> > I agree.

Actually I don't agree here, see my reply to Brendan earlier.

> > And in ES3 it is, unless the function either:

And I was thinking of (function(){}).constructor here, not (new
function(){}).constructor, when I said in ES3 it is. It isn't, which
is proper since the object is constructed by the anonymous function
object, not the Function object.

On 23/09/2007, Garrett Smith <dhtmlkitchen at gmail.com> wrote:
> When there is an anonymous constructor, we have the ability to get at
> the constructor property.

I don't see this as a problem - the constructor property should be the
function that actually constructed the object. Since ES3 allows any
value (except eval, I think) to be assigned to any variable (except
read only ones and those with special setters), the difference between
function declarations and function expressions is that declarations
are *by default* accessible through a variable name only, and function
expressions are *by default* accessible through the return value of
the expression only. There's no way to actually tell a function
derived from a function expression and a function derived from a
function declaration apart after the fact. (Well, except for that
function expressions make the name optional.)

So, if we want to be able to get at constructors at all, we can't
distinguish between how functions are derived - either we provide the
functionality, or we don't.

> function Animation(element){
>    var looped = 0;
>    var e = element;
>    function construct() {
>     this.loopCount = function() {
>      return looped;
>     }
>     this.loop = function() {
>      looped++;
>     }
>    }
>    return new construct();
>  }
> new new Animation().constructor().constructor; // construct

Sure. It's a closure, it exposes a property it's told to expose. (If
you use the new keyword, that it exposes the function object as the
constructor property of the constructed object should be expected.)
You can do this without the new keyword if you want to not expose the
function object, or use the delete keyword to explicitly remove it.

> On 9/23/07, liorean <liorean at gmail.com> wrote:
> > A disagreement of terminology I think. If you ask me, a function
> > instance is a function object. When using a function instance as a
> > constructor, you create an instance of that constructor (== function
> > instance) which is a plain, ordinary, mundane, normal,
> > run-of-the-mill, typical object. (Agh, ran out of synonyms!)

On 23/09/2007, Garrett Smith <dhtmlkitchen at gmail.com> wrote:
> F is a Function instance
> f is a function instance
> The terminology is confusing.

F is an instance of Function
f is an instance of F

Function is a function object
F is a function object
f is an object

As I see it, the meaning of "function instance" is an object that is
function-like, in other words a function object or a special host
object (like Function.prototype, which is a function but not an
instance of Function).
David "liorean" Andersson

More information about the Es4-discuss mailing list