Why is JavaScript prototyping?

So, on to my problem: Why the hell would you want to do this? Why would you not just put the play function in Guitar to begin with? Why declare an instance and then start adding methods later?

Javascript is not a ‘classical’ inheritance language. It uses prototypal inheritance. Its just the way it is. That being the case, the proper way to create an method on a ‘class’ is to put the method on the prototype. Note that I put ‘class’ in quotes, since strictly speaking JS has no notion of ‘class’. In JS, you work on objects, which are defined as functions.

You can declare the method in the function that defines Guitar, however, when you do that, every new guitar gets its own copy of the play method. Putting it on the prototype is more efficient in the runtime environment when you start creating Guitars. Every instance shares the same play method, but the context/scope is set when invoked so it acts a proper instance method you are used to in your classical inheritance language.

Note the difference. In the ‘why not this way’ example you posted, every time you create a new Guitar, you need to create a new play method that is the same as every other play method. If play is on the prototype, however, all Guitars borrow from the same prototype, so they all share the same code for play. Its the difference between x number of guitars, each with identical play code (so you have x copies of play) vs x number of guitars sharing the same play code (1 copy of play no matter how many Guitars). The trade off is of course that at runtime play needs to be associated with the object on which it is called for scoping, but javascript has methods that allow you to do that very efficiently and easily (namely the call and apply methods)

Many javascript frameworks define their own utilities for creating ‘classes’. Typically they allow you to write code like the example you said you would like to see. Behind the scenes, they are putting the functions on the prototype for you.


EDIT — in answer to your updated question, why can’t one do

function Guitar() {
    this.prototype.play = function()....
}

it has to do with how javascript creates objects with the ‘new’ keyword. See the second answer here — basically when you create an instance, javascript creates the object and then assigns the prototype properties. So this.prototype.play doesn’t really make sense; in fact, if you try it you get an error.

Leave a Comment