I wonder if someone could be kind enough to explain the function.prototype
thingie (thingie!!??) in OO javascript.
I come from a server side programming background, and may be I am not grasping the whole concept of prototypes,
Given the following snippets of code:
var animate=function(){};
animate.angular=function(){/*does something here*/};
animate.circular=function(){/*does something here*/};
And
var animate=function(){};
animate.prototype.angular=function(){/*does something here*/};
animate.prototype.circular=function(){/*does something here*/};
as far as I can tell, both the latter functions are callable via animate.angular(/*args*/)
and animate.circular(/*args*/)
so, I guess my question is, what are the merits of defining the functions in the second way? and how or why are they different?
Hope I made sense...
EDIT: Thankyou all for the enlightening answers, It's very hard to judge an answer here as being "Correct", so I'm gonna mark the one I feel made the most contribution...
You all have certainly given me more food for thought...
Even though it feels that way sometimes, javascript doesn't have classes, but works with prototypes. You define a prototype, then you can create copies of the prototype.
Starting with:
you can:
However, if you start with:
now you can
of course this is more interesting if you have instance variables.
Others have mentioned Douglas Crockford already, check Prototypal Inheritance on his site for more information. For contrast see Classical Inheritance.
Like gunderson, I also recommend Crockford's (slim) book JavaScript: The Good Parts.
I think you meant to set something equal to new animate() somewhere in your example. Without using new I'll elaborate a little on what happens:
Only the first two functions, #1 & #2, are callable from the animate variable.
If you create a new animate() you can call the next two, #3 & #4, (but not #1 or #2).
Also, animate() is a function but ani2 is not.
Although ani2 has already been created, you can add new members to it via the animate.prototype.
The animate variable doesn't inherit form it's prototype however.
Note that ani2 doesn't inherit members applied directly to the animate variable. It only inherits from animate.prototype.
You can also use the the this keyword inside a constructor function like animate to add instance members to new children.
Memory was automatically allocated for a separate instance of anime2.z only because it was modified, anime1 & anime3 still "share" a thrifty unmodified z.
The a, b, and c members are not "communal" in the same way. They were allocated immediately using this in the constructor, new Anime(), (not inherited from Anime.prototype). Also, the a member on the prototype would always be "individualized" by the constructor.
Never forget the new keyword or none of it works like it should. For example, this points to the global object in a constructor called without new.
Here's the output. And a second for Tom's suggesting the Douglas Crockford videos!
If you can spare 3 hours' time, I'd advise you to have a look at the "The JavaScript Programming Language" videos from YUI Theater. Speaker/teacher is Douglas Crockford, and he will give you a firm JS basis on which you can build.
Regards
Tom
Javascript is a weird language ... very powerful but not all that strongly structured compared with other languages...
The prototype is how JavaScript lets you save memory if you're going to be creating multiple instances of a class... So if you're using JS in an OOP way you should define your functions as part of the prototype. Also, there are ways to simulate inheritance using the prototype.
I highly recommend the book "Javascript, the Good Parts" for lots of great explanation about this.
Prototype-based OOP gives you freedoms Classy OOP doesn't.
If you really want to learn about it, like many said, read Crockford's explanations, you won't get any better resource than that.
If you want quick benefits:
Defining objects (which will represent what classes are in other languages) like this is WAY too nasty, so I will include a little tip in my answer:
Best way to build your system, is under a global namespace chosen by you, for example:
Cheers.