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?
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.
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.
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
> 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'
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.
And there's also this bit :
foo.constructor //-> constructor (inherited through [[prototype]])
oldPrototype.constructor= constructor2;
foo.constructor //-> constructor2
--
Jorge.
> 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.
> 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!
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.
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.
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.
<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