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

Garrett Smith dhtmlkitchen at gmail.com
Sun Sep 23 15:16:56 PDT 2007

On 9/23/07, liorean <liorean at gmail.com> wrote:
> 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.
F.prototype = {
    constructor : F

> > 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.

({}).hasOwnProperty("constructor"); //false.

{} is the same as new Object;

new Object goes through [[construct]]

The instance does not get a constructor property. No object instance
does. Well, none except objects that are prototype properties that
went through [[construct]]. This is confusing and makes the language
less clear to developers. It confuses me.

> > > 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.
I don't see a problem.

var d = new Date;
d.constructor == Date; // true
d.hasOwnProperty('constructor'); // false

The proposed change would have the result of:
d.hasOwnProperty('constructor'); // true
d.isPropertyEnumerable('constructor'); // false

> > > 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.

> 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 -

Right. Whether or not the Function object has a name is irrelevant.

the constructor property should be the
> function that actually constructed the object.

Exactly. That's what I'm talking about.

The fact that (new C).constructor === A; is true, by default of the
language, is counterintuitive.

[[construct]] gives a function instance a special prototype property.
That prototype property is an object, but not just an object, a
special object -- one that has a constructor property that is
specially flagged DontEnum. You lose that property the moment you give
a prototype property to F. Well, if the prototype property you give to
F is created through [[construct]], you don't.

You have to be careful.

new F().constructor == F; // true.
F.propertyIsEnumerable("prototype"); //true, Futhark and JScript say false.
F.prototype = {};
new F().constructor == F; // false.
F.prototype.constructor = F;
F.prototype.propertyIsEnumerable("constructor"); // true, JScript says false.

var complaint = false;
for( var prop in new F )
   complaint = true;

if(!complaint) alert('failure');
The browser support is pretty inconsistent, too.

> 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 expression/declaration, new Function -- the constructor
should all be Function

function FF(){}
FF.constructor === Function; // true
(Function()).constructor === Function; // true.
(new Function()).constructor === Function; // true.

The Object instance that is created in [[construct]] could have the
constructor property as DontEnum. This seems to be a compatibility
issue with ES3.

In ES3, you can't depend on the enumerability of an object's own
constructor property. This is because prototype objects have a
constructor property that is flagged DontEnum.

The idea is to make constructor a DontEnum property on all objects.

(not just ones that were created through [[construct]] to be used as
prototype properties).

constructor would be a default value given to the object in [[construct]]

What do you think?

> 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
> _______________________________________________
> Es4-discuss mailing list
> Es4-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es4-discuss

Programming is a collaborative art.

More information about the Es4-discuss mailing list