5

I have this function :

function Foo(){}

According to this picture :

enter image description here

>> Foo.prototype -> Foo {}

enter image description here

So if I write :

Foo.prototype.constructor

Now - it references to the constructor function which created the Foo{} object which is function Foo(){}

enter image description here

All ok.

So where is the question ?

Foo.prototype is an object instance --> Foo {}

And who is the constructor function of Foo{} ?

it is the the function Foo(){}

you can see it here in yellow :

enter image description here

ok

But I was told here that :

enter image description here

So Foo.prototype.__proto__ should reference to the prototype of function Foo(){} and not to Object.prototype !

If I translate it :

 __proto__ is the ctor's prototype
 _________________________________________________________________________________________
 Foo.prototype.__proto__ is the function Foo(){} Foo.prototype

but this is wrong

And i'm probably wrong because :

enter image description here

What am I missing ?

asked Oct 30, 2013 at 8:35

1 Answer 1

4

Note: First off, __proto__ is non-standard, use Object.getPrototypeOf, though for shortness, and because I'm lazy, I did use prototype quite a few times in this answer

Well, you're thrown of by your initial assumption, if I'm reading you correctly:

Foo.prototype -> Foo{}

The prototype of Foo (which is a constructor) is, by definition an instance of Foo. But, because a constructor is a function, and a constructor returns an object of a particular instance, the prototype will be an augmented Object either way.
I'm not a big fan of comparing prototypal ineritance to classical OOP, but think of it like this:

The Foo prototype is sort of a mutable class definition (you can add methods and properties as you go along), the constructor creates an object that augments this prototype, and adds another layer of properties/methods on an instance level.
Hence Foo.prototype instanceof Foo is true. But, Foo being an object:

Object.getPrototypeOf(Foo.prototype) === Object.prototype

is true. Just as

Object.getPrototypeOf(Array.prototype) === Object.prototype.

Translate this to JS (prototype)-speak, and you get something like:

For each function object JS creates, this object is assigned a prototype property. The prototype property is an instance of Object, but it has 1 special property.
If one attempts to access a property or method on an object, and JS cannot find this property defined at the instance level, JS will attempt to resolve the name on the prototype property:

instance.nonExistantProperty;
//js scans instance variable, doesn't find property:
instance.prototype.nonExistantProperty
//js uses prototype, if not found:
instance.prototype.prototype.nonExistantProperty
//all the way up to Object.prototype, which does not have a prototype, so here an exception is raised (TypeError is thrown)

Here's a short schematic representation of this lookup, which I copied from one of my older posts here, it might be worth a look, also check the linked answers at the bottom, they go into even more details on this matter

[ F.divide ]<=========================================================\ \
F[divide] ===> JS checks instance for property divide | |
 /\ || | |
 || || --> property found @instance, return value-------------------------------| |
 || || | |
 || ===========> Function.prototype.divide could not be found, check prototype | |
 || || | |
 || ||--> property found @Function.prototype, return-----------------------| |
 || || | |
 || ==========> Object.prototype.divide: not found check prototype? | |
 || || | |
 || ||--> property found @Object.prototype, return---------------------|_|
 || || |=|
 || =======>prototype is null, return "undefined.divide"~~~~~~~~~~~~~~~|X|
 || \ /
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~< TypeError can't read property 'x' of undefined

That's basically it.

Now, perhaps you're also a tad thwarted as to why Foo.prototype.constructor references the Foo function.
Again, this is quite easy, because each instance is expected to contain all information you might require to determine which type of object you're dealing with:

function Foo{}
var inst = new Foo();
console.log(inst.constructor);//references the constructor function

Remember, all instances returned by Foo return an object, that references all of the prototype properties, and (optionally) some properties at instance level, too.

Why, then, would you even bother creating such instances? Again this is perfectly simple: changing an instance, does not change the prototype:

console.log(Foo.prototype.constructor === inst.constructor);//true
inst.constructor = function(){};//override constructor property
console.log(Foo.prototype.constructor === inst.constructor);//false, prototype did not change
answered Oct 30, 2013 at 8:49
Sign up to request clarification or add additional context in comments.

5 Comments

I'm sorry - I didnt understand the "augmented Object either way" part. Foo.prototype is Foo{} instance Object. and proto should reference to its ctor's prototype. so who is Foo{} ctor ? it is the Function Foo(){} . ( and again - i'm wrong) proof --i.sstatic.net/n4PMC.png.
@RoyiNamir: Foo{}'s constructor is Foo.prototype.constructo, because Foo.prototype is Foo{}, just like, on your screenshot g.constructor is functoin Foo. The Foo.prototype, like I said, is an automatically assigned property, like an array has a magic length prop. But basically, a prototype is just an Object, so its real constructor is the object constructor, but because this prototype belongs to a constructor function, its constructor property is set to reference that function. That's all really
I think you're right becuase here (i.sstatic.net/qXy97.png) I see that new Object()'s __proto__ is indeed object.prototype. and there is no difference between new Foo() vs Foo{}
I've been thinking of it again and it doesn't fit (in my head): what do you mean by "its real constructor" ? the ctor of Foo{} is function Foo() and the prototype is Foo.prototype so why does Foo{}'s __proto__ which should refer its ctor prototype - refers to Object.prototype ?
All objects come with a prototype. This prototype is an object all on its own. You may have seen people do this: Foo.prototype = { someF: function(){}, anotherF: function(){}}. A prototype is just a property of a constructor, that happens to be an object. Hence, all prototypes are just objects, and their actual constructor is Object. The constructor property just refers back to the constructor the prototype obkect belongs to. Nothing in your code refers to the object.prototype directly, but at the root of every object, lies the Object.prototype

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.