0

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::

JS Heirarchy map

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

Revised Diagram 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.

asked Apr 26, 2016 at 21:05
13
  • 1
    "why is prototype needed 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 between Cat and Cat.prototype") ? Commented Apr 26, 2016 at 21:19
  • By the way, if you wanted Cat to be an extension of Animal, the proper way to do it is: Cat.prototype = Object.create(Animal.prototype); Animal.prototype.constructor = Animal; Commented Apr 26, 2016 at 22:01
  • @vtange what would be the benefit of what you just explained as opposed to just having Cat.prototype = new Animal(): which is having the Cat prototype be an instance of Animal. (I think I said that correct) Commented Apr 26, 2016 at 22:24
  • 1
    If you did it your way, you're saying "all Cats should be the same as (create a new Animal with no inputs)." That means Cats are the same as Animals with no name and gender. See more at stackoverflow.com/questions/16100471/… Commented Apr 26, 2016 at 22:26
  • @vtange I read the SO post and understand why you suggest that now, but why are you using Animal.prototype.constructor = Animal. From my reading, I thought you would need to instead do it to Cat as such: Cat.prototype.constructor = Cat. This way, this context will refer to the Cat constructor and not the Animal constructor. Is this correct? Commented Apr 26, 2016 at 22:40

3 Answers 3

2

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.

answered Apr 26, 2016 at 21:08
Sign up to request clarification or add additional context in comments.

9 Comments

To be precise, Cat.color = null; sets the color property on the Cat function object. Not on an instance of Cat, nor on the Cat prototype.
@JordanHendrix, thank you. I guess what I'm interested in is why JavaScript is designed to need prototypes. Why couldn't the actual Cat function object be the basis of inheritance and instantiation, instead of some abstract prototype concept?
@inthenameofmusik: That would imply that every instance of Cat is a function because Cat is a function.
I get it, its kinda silly to people but its just the way js does it : javascriptissexy.com/…
@inthenameofmusik: "instead of some abstract *prototype concept"* Note that JavaScript isn't the only language which uses prototypes, although the majority of the others are not popular. en.wikipedia.org/wiki/Prototype-based_programming
|
1

"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.

answered Apr 26, 2016 at 21:30

4 Comments

FWIW, primitive values are not objects. No constructor is called. Only when a primitive value is accessed like an object (property access), it is temporarily converted to an object.
Yep, correct. This is just an analogy I made to help OP understand why we work with prototypes.
@FelixKling would you mind looking at the edit I made with the diagram and let me know if my way of diagramming this makes sense?
@vtange if you wouldn't mind commenting on the correctness of the diagram I uploaded at the top. Thank you.
1

Several things to remind;

  1. 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.
  2. 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.
  3. 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 as this.name or this.color however 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.
answered Apr 26, 2016 at 21:28

6 Comments

" If an constructor function has variables defined with a preceding this." Technically, those are not variables anyway.
@Redu Thank you, this really helped me get closer to understanding. So... the reason of needing a function constructor and a prototype instead of just having a function constructor is so that non-specific properties can be referenced down the chain, therefore saving memory instead of passing them onto each instance. Is this the only reason this constructor/prototype design is used in JavaScript or am I missing some more reasons? I'm wondering if the tradeoff of all this complexity is worth the performance gain.
@inthenameofmusik: "the tradeoff of all this complexity" I'd argue that prototypes are not much more complex than variable scope, which basically works in a very similar way. A very practical advantage of prototypes are polyfills: You can easily add support for new APIs by extending the respective prototype (e.g. Array.prototype) without any impact on the user / creator of arrays.
@inthenameofmusik you got it right.. that's how it is. Imagine all the array and object functions those reside in the Array.prototype or Object.prototype which are directly accessible from all the objects and arrays instantiated in your code. What else could be better?
@Redu thank you. I'm getting it now. Would you mind commenting on the diagram I posted above, whether it's a correct representation of what's going on. I believe I should have animal.prototype pointing to a new object.prototype box but I'm not sure what the object.prototype box should be pointing to.
|

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.