f.prototype and constructor (js)

http://javascript.info/function-prototype

[DRAWING HERE]

In modern JavaScript we can set a prototype using __proto__.

But in the old times, there was another (and the only) way to set it: to use a “prototype” property of the constructor function.

It is known that, when “new F()” creates a new object…

the new object’s [[Prototype]] is set to F.prototype

In other words, if function F has a prototype property with a value of the object type, then the “new” operator uses it to set [[Prototype]] for the new object.

Setting Rabbit.prototype = animal literally states the following: “When a new Rabbit is created, assign its [[Prototype]] to animal”.

Constructor Property

As stated previous, we have the “prototype” property point to whatever object we want as the parent class to be inherited from future “new”-ed functions.

However, what is this “prototype” property before our assignment?
Every function has the “prototype” property even if we don’t supply it.

The default “prototype” property points to an object with the only property constructor that points back to the function itself.

You can check it like this:

Rabbit prototype by default

By default whatever objects created from “new Rabbit()” will inherit from Rabbit.
The instance ‘rabbit’ has constructor property which points to Rabbit.

We can use constructor property to create a new object using the same constructor as the existing one.

Like here:

Future manipulations of the prototype property

JavaScript itself does not ensure the right “constructor” value.

Yes, it exists in the default object that property prototype references, but that’s all. What happens with it later – is totally on us.

In this example, we see that we repointed the prototype to a totally different object. Thus, other instances of Rabbit, will be deriving from the object with property jumps: true.

The assumption that instances of Rabbit will have a ‘Rabbit’ constructor will then be false.

So, to keep the right “constructor” we can choose to add/remove properties to the default “prototype” instead of overwriting it as a whole:

Or you can reconstruct it yourself. Just make sure to include the constructor property and set it to your this object:

The only thing F.prototype does: it sets [[Prototype]] of new objects when “new F()” is called.

The value of F.prototype should be either an object or null: other values won’t work.

The “prototype” property only has such a special effect when is set to a constructor function, and invoked with new.

By default all functions have F.prototype = { constructor: F }, so we can get the constructor of an object by accessing its “constructor” property.

Gotchas

The assignment to Rabbit.prototype sets up [[Prototype]] for new objects. The new object ‘rabbit’ then points to Rabbit. The instance rabbit’s [[Prototype]] then is pointing to Rabbit’s default prototype object with its constructor property.

Then Rabbit’s prototype points to an empty object. However, rabbit’s [[Prototype]] already is referencing Rabbit’s default prototype object with its constructor property. Hence that’s why rabbit.eats is true.

Problem 1

solution: true

prototype_answer1

Problem 2

Solution: false

prototype_answer2

Problem 3

Solution:

All delete operations are applied directly to the object. Here delete rabbit.eats tries to remove eats property from rabbit, but it doesn’t have it. So the operation won’t have any effect.

prototype_answer3

Problem 4

Solution
prototype_answer4