Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

constructors in JS

1 view
Skip to first unread message

xdevel1999

unread,
Mar 17, 2009, 9:37:03 AM3/17/09
to
Hi,

if I Have

var f = function Foo(){}

new f().constructor.prototype.constructor === Foo is true???

here the prototype object should have Object not Foo as constructor.

and

why new f().constructor.prototype.constructor.prototype.constructor is
always the same
while

new f().__proto__.__proto__.__proto__ end correctly with null?

David Mark

unread,
Mar 17, 2009, 10:50:10 AM3/17/09
to
On Mar 17, 9:37 am, xdevel1999 <xdevel1...@gmail.com> wrote:
> Hi,
>
> if I Have
>
> var f =  function Foo(){}

Don't name function expressions.

>
> new f().constructor.prototype.constructor === Foo is true???

Is that a question???

>
> here the prototype object should have Object not Foo as constructor.

According to whom?

>
> and
>
> why new f().constructor.prototype.constructor.prototype.constructor is
> always the same

Because you are going around in circles.

> while
>
> new f().__proto__.__proto__.__proto__ end correctly with null?

The prototype property represents just one link in the chain.

Hubert

unread,
Mar 17, 2009, 12:42:32 PM3/17/09
to
> var f =  function Foo(){}
> new f().constructor.prototype.constructor === Foo is true???

Please, let me clarify your example, and then look at the following
chain of assertions:

var Foo = function(){};
alert( Foo.hasOwnProperty( "prototype" ) === true );
alert( Foo.prototype.hasOwnProperty( "constructor" ) === true );
alert( Foo.prototype.constructor === Foo );
alert( Foo.protype instanceof Foo === false ); // In contradiction to
the line before???

var foo = new Foo();
alert( foo.hasOwnProperty( "constructor" ) === false );
alert( foo.constructor === Foo )
alert( foo instanceof Foo === true ); // In agreement with the line
before! Very well!

It shows quite clearly that each function (Foo) has a 'prototype'
property which in turn has a 'constructor' property, which in turn is
identical to the original function.

An instance (foo) of a constructor function (Foo), on the other hand,
has NO 'constructor' property OF ITS OWN, only by virtue of the
prototype chain, and THAT constructor property, of course, is
identical to the original function, again.
In other words: foo.constructor === Foo.prototype.constructor === Foo.

From this follows:
foo.constructor.prototype.constructor === Foo.prototype.constructor
=== Foo.

So, your observation


> new f().constructor.prototype.constructor.prototype.constructor is always the same

has a simple reason.

Also note that while both Foo.prototype and foo seem to have the
constructor Foo,
only foo is an instance of Foo, as shown clearly by the instanceof
operator.
So, having some 'constructor' property and really being an instance of
some function are quite different things.

Now, what about the '__proto__' property and why does the __proto__
chain end with null?
First of all, the '__proto__' property is implementation specific with
certain browsers.

An object like foo has no 'prototype' property, only its constructor
function does.
What foo does have, though, is an "internal" property which the
standard calls [[prototype]].
See: ECMA-262 Section 8.6.2.
But you cannot officially access [[prototype]].
Certain browsers give you __proto__ which is assumed to be
[[prototype]].
Therefore its chain ends nicely with null, as the standard requires.

Remember, that the so-called "prototype chain" which is so often
mentioned in the literature, is really the [[prototype]] chain, which
for some browsers is the __proto__ chain.
The "constructor.prototype" chain is really something else, as is
shown by its stationary character.

Thomas 'PointedEars' Lahn

unread,
Mar 17, 2009, 2:39:41 PM3/17/09
to
Hubert wrote:
>> var f = function Foo(){}
>> new f().constructor.prototype.constructor === Foo is true???
>
> Please, let me clarify your example, and then look at the following
> chain of assertions:
>
> var Foo = function(){};
> alert( Foo.hasOwnProperty( "prototype" ) === true );
> alert( Foo.prototype.hasOwnProperty( "constructor" ) === true );
> alert( Foo.prototype.constructor === Foo );
> alert( Foo.protype instanceof Foo === false ); // In contradiction to
^^
> the line before???

A `to' is missing there; `undefined' cannot be a `Foo' object. However, the
result of the left-hand side is `false' even if that error was corrected,
because Object.prototype (the prototype of the object Foo.prototype would
refer to) is located after Foo.prototype in the prototype chain (works as
designed.)

> var foo = new Foo();
> alert( foo.hasOwnProperty( "constructor" ) === false );
> alert( foo.constructor === Foo )
> alert( foo instanceof Foo === true ); // In agreement with the line
> before! Very well!

You wrote it correctly here; Foo.prototype is in `foo's prototype chain.
However, the ` === true' is most superfluous as `instanceof' is an operation
that results in a boolean value.


PointedEars

Lasse Reichstein Nielsen

unread,
Mar 17, 2009, 5:52:16 PM3/17/09
to
xdevel1999 <xdeve...@gmail.com> writes:

> if I Have
>
> var f = function Foo(){}
>
> new f().constructor.prototype.constructor === Foo is true???

No. There is no variable called Foo after the previous code.
Now, if you had used a function declaration:
Function Foo(){}
and then create an object using
var obj = new Foo();
then the object relations are the following:

+--------+
| obj |
+--------+
|
[Proto]
|
v
+--------------+ ---constructor--> +---------+
|Foo.prototype | | Foo |
+--------------+ <--prototype----- +---------+
| |
[Proto] [Proto]
| |
v v
+----------------+ +------------------+
|Object.prototype|<--[Proto]---|Function.prototype|
+----------------+ +------------------+

> here the prototype object should have Object not Foo as constructor.

No, obj.constructor.prototype.constructor is exactly Foo.

Remember that "constructor" is just a property of Foo.prototype that
all instances of Foo *inherits*. It's not a property of objects that
point to their constructor (if any).

> and
>
> why new f().constructor.prototype.constructor.prototype.constructor is
> always the same
> while
>
> new f().__proto__.__proto__.__proto__ end correctly with null?

Because __proto__ follows the prototype chain, while the Foo.prototype
and Foo.prototype.constructor properties merely points back and forth
betwen Foo and Foo.prototype.

/L
--
Lasse Reichstein Holst Nielsen
'Javascript frameworks is a disruptive technology'

Jorge

unread,
Mar 17, 2009, 7:04:29 PM3/17/09
to
On Mar 17, 5:42 pm, Hubert <hubert.kau...@travelbasys.de> wrote:
> (...)

> The "constructor.prototype" chain is really something else, as is
> shown by its stationary character.

The "constructor.prototype" chain isn't a chain it's a |new Object();|
like this :

constructor.prototype= {
constructor: constructor
}

that's automatically created and assigned to the .prototype property
of every function (be it constructor or not) when the function is
created:

(function(){}).prototype === Object.prototype //-> false, different
objects.
(function(){}).prototype instanceof Object //-> true
(function(){}).prototype === (function(){}).prototype //false,
different objects

OTOH, objects created by a |new constructor();| :

constructor= function constructor () {};
foo= new constructor();
foo instanceof constructor //-> true

are instances of a given constructor if and only if their (invisible)
[[prototype]] (that's inmutable) points to the object that's
**currently** assigned to that constructor's .prototype:

var oldPrototype= constructor.prototype;

constructor.prototype= {}; //A new, different object
foo instanceof constructor //-> false

constructor.prototype= oldPrototype;
foo instanceof constructor //-> true

constructor2= function constructor2 () {};
constructor2.prototype= oldPrototype;

foo instanceof constructor2 //-> true
foo instanceof constructor //-> true


(AFAIK)
--
Jorge.

Jorge

unread,
Mar 17, 2009, 7:12:13 PM3/17/09
to
On Mar 18, 12:04 am, Jorge <jo...@jorgechamorro.com> wrote:

And there's also this bit :

foo.constructor //-> constructor (inherited through [[prototype]])
oldPrototype.constructor= constructor2;
foo.constructor //-> constructor2

--
Jorge.

Hubert

unread,
Mar 18, 2009, 3:41:10 AM3/18/09
to
On Mar 17, 7:39 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:

> Hubert wrote:
> >    alert( Foo.protype instanceof Foo === false ); // In contradiction to

> A `to' is missing there; `undefined' cannot be a `Foo' object.  

Thomas,
sorry, that was a typo.
It should, indeed, read:

alert( Foo.prototype instanceof Foo === false );

I am glad the overall conclusion still holds after correction.

> However, the ` === true' is most superfluous as `instanceof' is an operation
> that results in a boolean value.

Yes, absolutely.
But I chose to leave the "===" in there for clearer emphasis.

xdevel1999

unread,
Mar 18, 2009, 8:37:21 AM3/18/09
to

First thanks for your detailed answers but
really I don't understand WHY is true this assertion:

> It shows quite clearly that each function (Foo) has a 'prototype'
> property which in turn has a 'constructor' property, which in turn is
> identical to the original function.

if Foo.prototype points to an empty Object than its constructor should
be Object
as an instance of Foo has Foo as contructor

var Foo = function(){}

var f = new Foo();

f.constructor == Foo // true

Foo.prototype.constructor == Object // false

maybe I'm stupid but really I don't understand!

If Foo.prototype.constructor == Object had been TRUE

than I'd could have that

Foo.prototype.constructor.prototye.constructor.prototype == new f
().__proto__.__proto__.__proto__

both had returned null but in the first case exists a circularity...
that make me return always back...

Arghhh I'm very frustrated!


Richard Cornford

unread,
Mar 18, 2009, 9:05:03 AM3/18/09
to
xdevel1999 wrote:
>
> First thanks for your detailed answers but
> really I don't understand WHY is true this assertion:
>
>> It shows quite clearly that each function (Foo) has a 'prototype'
>> property which in turn has a 'constructor' property, which in
>> turn is identical to the original function.
>
> if Foo.prototype points to an empty Object than its constructor
> should be Object

The - prototype - property of a function is not an 'empty' object. It
could be argued that no javascript objects are 'empty', but even
disregarding the inherited object methods step 9 in the function
creation algorithm (ECMA 262 3rd Ed. Section 13.2) assigns an object to
the - prototype - property of the new function and then step 10 sets a -
constructor - property of that object to be a reference to the new
function. If the object were 'empty' upon being assigned to the
function's - prototype - property it certainly is not 'empty' once it
has had a - constructor - property added to it.

> as an instance of Foo has Foo as contructor
>
> var Foo = function(){}
>
> var f = new Foo();
>
> f.constructor == Foo // true
>
> Foo.prototype.constructor == Object // false
>
> maybe I'm stupid but really I don't understand!
>
> If Foo.prototype.constructor == Object had been TRUE
>
> than I'd could have that
>
> Foo.prototype.constructor.prototye.constructor.prototype ==
> new f().__proto__.__proto__.__proto__

As has already been stated; an object's prototype chain starts with its
*internal* [[Prototype]] property (exposed in JavaScript(tm) as
__proto__), the exposed - prototype - properties of function objects are
there as a means of manipulating the values that will become the
internal [[Prototype]] values of new object if those functions are used
as constructors, but they are not the same thing.

> both had returned null but in the first case exists a
> circularity...

<snip>

Yes, a function object exists, it has a - prototype - property that
refers to another object, that object has a - constructor - property
that refers back to the function object; that is a circle.

Richard.

Jorge

unread,
Mar 18, 2009, 9:38:44 AM3/18/09
to
On Mar 18, 1:37 pm, xdevel1999 <xdevel1...@gmail.com> wrote:
> First thanks for your detailed answers but
> really I don't understand WHY is true this assertion:
>
> > It shows quite clearly that each function (Foo) has a 'prototype'
> > property which in turn has a 'constructor' property, which in turn is
> > identical to the original function.
>
> if Foo.prototype points to an empty Object than its constructor should
> be Object s an instance of Foo has Foo as contructor

Foo.prototype is an object like this one : (*)

{
constructor: Foo
}

That object is **not** there to query about Foo's nature. It is there
because it's the object from which Foo's instances (new Foo()s) will
inherit, and that's why it has the .constructor property set to point
to Foo.

> var Foo = function(){}
>
> var f = new Foo();
>
> f.constructor == Foo // true
>
> Foo.prototype.constructor == Object // false
>
> maybe I'm stupid but really I don't understand!
>
> If  Foo.prototype.constructor == Object had been TRUE

If Foo.prototype.constructor were Object, instances of Foo would have
Object as its constructor, which is wrong.


(*)That object is created automatically for each and every function
(be it a contructor or not) when the function is created, and
initialized in this way:

When function Foo () {}; is created:
Foo.prototype is set to = { constructor: Foo }; <-that's an object in
literal notation.

(Although this object gets created and assigned automatically it can
be exchanged for another (different) one at any time.)
--
Jorge.

Jorge

unread,
Mar 18, 2009, 10:06:14 AM3/18/09
to
On Mar 18, 1:37 pm, xdevel1999 <xdevel1...@gmail.com> wrote:
>
> If  Foo.prototype.constructor == Object had been TRUE
>

Ok, I think that I see why you're puzzled:

Foo.prototype has been constructed by Object(), so why its constructor
isn't Object ?

Because its own .constructor property is shadowing the
inherited .constructor property:

for example, if you create an new empty object:

javascript:alert({}.constructor); //-> Object() as expected,
(inherited).

But when the new object that you're creating has an own
property .constructor it shadows the inherited one:

javascript:alert({constructor: "Foo"}.constructor); //-> Foo

--
Jorge.

John G Harris

unread,
Mar 18, 2009, 1:31:28 PM3/18/09
to
On Wed, 18 Mar 2009 at 06:38:44, in comp.lang.javascript, Jorge wrote:

<snip>


>When function Foo () {}; is created:
>Foo.prototype is set to = { constructor: Foo }; <-that's an object in
>literal notation.
>
>(Although this object gets created and assigned automatically it can
>be exchanged for another (different) one at any time.)

Which is why an object need not have a constructor property. It depends
how the object's prototype objects were made.

John
--
John Harris

0 new messages