30

I realize this has been asked hundreds of times, however, I can't seem to grasp the concept of "why" prototypes in JavaScript are proper, as apposed to imitating classes (yes, I know JavaScript is a prototypical based language - I've gathered that much).

Like many other people striving to make JavaScript an everyday language that I use, I'm use to the regular OOP class style, as I've played around in Java (and used classes in ActionScript as well as PHP). However, while I think I understand how prototypes work, I can't seem to understand why they're needed.

Here's my sample script of how I'm currently understanding prototypes in JavaScript:

var Apple = function() { // An apple? }; Apple.prototype.color = "red"; Apple.prototype.changeColor = function(new_color) { this.color = new_color; }; Apple.prototype.getColor = function() { alert('color: '+this.color); }; var apple1 = new Apple(); var apple2 = new Apple(); apple2.changeColor("green"); apple1.getColor(); apple2.getColor(); 

...I had assumed that maybe the prototype meant that it shared the same object instead of just creating a new object each time - however, it obviously isn't the case since both apple1 and apple2 have different colors, still (after running said script).

Then I wrote it in what's more of a object-oriented script:

var Apple = function() { this.color = "red"; this.changeColor = function(new_color) { this.color = new_color; }; this.getColor = function() { alert('color: '+this.color); }; }; var apple1 = new Apple(); var apple2 = new Apple(); apple2.changeColor("green"); apple1.getColor(); apple2.getColor(); 

With the exact same results (as expected). ...Why is the latter code not recommended? I have no problem using prototypes (assuming I used them correctly), but I need to understand the concept of "why".

...Any help?

2 Answers 2

32

...I had assumed that maybe the prototype meant that it shared the same object instead of just creating a new object each time...

It does. There's one prototype object that is shared among all instances created from the constructor.

...however, it obviously isn't the case since both apple1 and apple2 have different colors, still (after running said script).

For certain types (for example number, boolean, null, undefined, or string), when you change a property that exists on the prototype object via this.color for example, it will create a color property on the instance. The prototype remains unaffected so that new instances will have the default color defined in the prototype.

If you had updated a member of an Array or an Object that was referenced by a property of the prototype object, the change would be seen among all instances.

...Why is the latter code not recommended?

Because you're constructing new identical functions with the creation of each new instance instead of sharing one instance of the functions via the prototype object.


To expand a little more, I'd point out that when your function is called as a constructor by using the new keyword, this in the constructor is the new instance. So any property you add to this is being added to the instance.

var Apple = function() { // Here "this" is the object being constructed. As such, we're adding // a property "rotten" to every instance created this.rotten = false; }; // adding a "color" property to the prototype object Apple.prototype.color = "red"; // set the property "color" on the instance to the value of "new_color" Apple.prototype.changeColor = function(new_color) { this.color = new_color; }; // first check to see if this instance has its own "color" property. If so, // use it. If not, look at the prototype object to see if it exists. Apple.prototype.getColor = function() { alert('color: '+this.color); }; // two new instances each have their own "rotten" property, and don't have a // "color" property. Both share the prototype object, so if "color" is // requested, it will come from there var apple1 = new Apple(); var apple2 = new Apple(); // This will add an "color" property to the "apple2" instance apple2.changeColor("green"); // Doesn't have a "color" property, so it looks to the prototype object apple1.getColor(); // Has a "color" property, so it uses that instead of the "color" on the prototype apple2.getColor(); 
Sign up to request clarification or add additional context in comments.

4 Comments

That actually helped tremendously; thank you. Upon referencing Apple.prototype.color, I can see that it still is "red", which reconfirms my original thought about prototypes referencing a single object. It's still a bit confusing, as I want to specify my methods straight into ... well, functions, but I think I may be getting the hang of it. Thanks, again.
@clicheName: You're welcome. I updated with a little more info, but it sounds like you've got a grasp on it.
am I understanding it correctly? I feel, they are somewhat like static variable and methods in java which are shared among objects...
@vishwanath: Sorry for the delay. The prototype object is certainly shared. If someone tries to access a property that doesn't exist on an instance, it will look to see if it exists on the prototype. I'm not so familiar with Java, but after reading about static variables, I'd say they are definitely not the same. Instead the prototype is javascript's mechanism for inheritance, where the prototype object can actually be an instance of another class causing a prototype chain of the instance, to its prototype, to that instance's prototype until you get to the end.
6

prototype allows you to add methods and properties to a class and it will apply it not only to the class, but also any current object instances of that class.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.