I'm studying prototypes right now and think that I'm almost there but I'm a bit confused on one topic.
Let's say we have:
function Animal(name, gender) {
this.name = name;
this.gender = gender;
}
function Cat(species) {
this.species = species;
}
Cat.prototype.color = null;
Cat.prototype = new Animal();
My question is, why is prototype needed at all for new properties?
Why couldn't we do:
Cat.color = null;
EDIT::
All the white blocks are from a uml diagram from another SO post. I added the orange boxes to suit this example that I've provided. Does this diagram I've added to still make sense?
My main problem I believe is that I was making the function constructors and the actual prototype objects too similar when in fact they're completely different things. One's a function and one's an object.
EDIT 2
With this diagram, I'm trying to clarify how the constructor property interacts and what it is exactly connected to, and more specifically, how it affects the use of this. Any comments on the validity would help.
3 Answers 3
Good question:
Cat.color = null; sets the color only on that one Cat, if you put it on the prototype any 'Cat' you instantiate afterwards will also contain a color property.
Lets say you have something like var tabby = new Cat('feline') with the code above it without the prototype tabby won't have a color.
9 Comments
Cat.color = null; sets the color property on the Cat function object. Not on an instance of Cat, nor on the Cat prototype.Cat function object be the basis of inheritance and instantiation, instead of some abstract prototype concept?Cat is a function because Cat is a function."Everything in Javascript is an Object"
Ever wonder why you can use .toString() on say the number 50 without having written Number.toString = function(){....?
Because it's built-into Javascript. All Number.prototypes have the .toString method. And the list goes on for Arrays, Objects, Strings, etc.
Every time you write a Number in JS, imagine (no constructor is really called) calling a Number constructor function similar to your constructor functions for Animal & Cat.
That's what constructor functions do. They create an instance of (theirname).prototype. That's why function Animal() makes something of Animal.prototype and so on.
function Animal() and function Cat() otherwise have nothing to do with Animal.prototype and Cat.prototype. If you actually made a new Animal with new Animal() and then changed the constructor, the new Animal you just made wouldn't be updated, because it was constructed before the constructor changed.
Let's say you make a Cat "Hobbes"
Then after that, when you say Cat.prototype.color = null;, you're saying all objects of Cat.prototype should have a 'null' value for color. This will update Cats you constructed before, since now when you try to find Hobbe's color, it will spit undefined since you didn't give a color to Hobbes himself in function Cat(), but then JS will backtrack to Hobbe's Cat.prototype and find that color is actually null.
Hope that helps.
4 Comments
Several things to remind;
- A constructor function is used to instantiate new objects. If a constructor function has variables defined with a preceding
this.keyword then those will be the properties of the instantiated object. The variables defined with preceding var keyword won't be a part of the instantiated object. - The objects instantiated by a constructor function will have their prototypes assigned to the constructor function's prototype hence they have direct access to the constructor function's prototype. This means they can use (share) the properties and functions within the constructor function's prototype as if they are their own.
- The prototype is very useful when you think of instantiating thousands of objects from a constructor function. The unique properties of each object such as name, id, color or whatever should be defined with a preceding
this.in the constructor. Such asthis.nameorthis.colorhowever the functionalities that they are expected to share should be defined in the constructors prototype since obviously it would be a waste of memory to reserve a room for them within each instantiated object.
6 Comments
this." Technically, those are not variables anyway.Array.prototype) without any impact on the user / creator of arrays.animal.prototype pointing to a new object.prototype box but I'm not sure what the object.prototype box should be pointing to.Explore related questions
See similar questions with these tags.
prototypeneeded at all for new properties" Is this a question about why Brendan Eich decided to design the language in this way (which can only be answered by him), or is this purely a technical question (in the sense of "what is the difference betweenCatandCat.prototype") ?Catto be an extension ofAnimal, the proper way to do it is:Cat.prototype = Object.create(Animal.prototype); Animal.prototype.constructor = Animal;Cat.prototype = new Animal(): which is having theCatprototype be an instance ofAnimal. (I think I said that correct)Animal.prototype.constructor = Animal. From my reading, I thought you would need to instead do it toCatas such:Cat.prototype.constructor = Cat. This way,thiscontext will refer to theCatconstructor and not theAnimalconstructor. Is this correct?