views:

2301

answers:

6

I'm not that in to dynamic programming but I've written my fair share of JavaScript code. I never really got my head around this prototype-based programming, does any one who know how this works?

var obj = new Object();
obj.prototype.test = function() { alert('Hello?'); };
var obj2 = new obj();
obj2.test();

I remember a lot talk I had with people a while back, I'm not actually sure what the hell I'm doing. As I understand it, there's no concept of a class, it's just an object, and instances of those objects are clones of the original, right?

But what is the exact purpose of this ".prototype" property in JavaScript? How does it relate to instantiating objects?

Update: correct way

var obj = new Object(); // not a functional object
obj.prototype.test = function() { alert('Hello?'); }; // this is wrong!

function MyObject() {} // a first class functional object
MyObject.prototype.test = function() { alert('OK'); } // OK

Also these slides really helped a lot.

+2  A: 

prototype allows you to make classes. if you do not use prototype then it becomes a static.

Here is a short example.

var obj = new Object();
obj.test = function() { alert('Hello?'); };

In the above case, you have static funcation call test. This function can be accessed only by obj.test where you can imagine obj to be a class.

where as in the below code

function obj()
{
}

obj.prototype.test = function() { alert('Hello?'); };
var obj2 = new obj();
obj2.test();

The obj has become a class which can now be instantiated. Multiple instances of obj can exist and they all have the test function.

The above is my understanding. I am making it a community wiki, so people can correct me if I am wrong.

Ramesh
-1: `prototype` is a property of constructor functions, not instances, ie your code is wrong! Perhaps you meant the non-standard property `__proto__` of objects, but that's a whole different beast...
Christoph
@Christoph - Thanks for pointing it out. I have updated the sample code.
Ramesh
This a sort of good answer, but there's more to it.
John Leidegren
There's so much more to it... Plus JavaScript is not a class-based language - it deals with inheritance via prototypes, you need to cover the differences in more detail!
J-P
+1  A: 

what is the exact purpose of this ".prototype" property?

The interface to standard classes become extensible. For example, you are using the Array class and you also need to add a custom serializer for all your array objects. Would you spend time coding up a subclass, or use composition or ... The prototype property solves this by letting the users control the exact set of members/methods available to a class.

Think of prototypes as an extra vtable-pointer. When some members are missing from the original class, the prototype is looked up at runtime.

dirkgently
A: 

Javascript doesn't have inheritance in the usual sense, but it has the prototype chain.

prototype chain

If a member of an object can't be found in the object it looks for it in the prototype chain. The chain consists of other objects. The prototype of a given instance can be accessed with the __proto__ variable. Every object has one, as there is no difference between classes and instances in javascript.

The advantage of adding a function / variable to the prototype is that it has to be in the memory only once, not for every instance.

It's also useful for inheritance, because the prototype chain can consist of many other objects.

Georg
FF and Chrome supports __proto__, but not IE nor Opera.
some
+8  A: 

John Resig has a few slides on function prototypes that were helpful to me when looking into the subject (you can also make changes to the code and see what happens...)

http://ejohn.org/apps/learn/#64

sighohwell
+10  A: 

Every JavaScript object has an internal property called [[Prototype]]. If you look up a property via obj.propName or obj['propName'] and the object does not have such a property - which can be checked via obj.hasOwnProperty('propName') - the runtime looks up the property in the object referenced by [[Prototype]] instead. If the prototype-object also doesn't have such a property, its prototype is checked in turn, thus walking the original object's prototype-chain until a match is found or its end is reached.

Some JavaScript implementations allow direct access to the [[Prototype]] property, eg via a non-standard property named __proto__. In general, it's only possible to set an object's prototype during object creation: If you create a new object via new Func(), the object's [[Prototype]] property will be set to the object referenced by Func.prototype.

This allows to simulate classes in JavaScript, although JavaScript's inheritance system is - as we have seen - prototypical, and not class-based:

Just think of constructor functions as classes and the properties of the prototype (ie of the object referenced by the constructor function's prototype property) as shared members, ie members which are the same for each instance. In class-based systems, methods are implemented the same way for each instance, so methods are normally added to the prototype, whereas an object's fields are instance-specific and therefore added to the object itself during construction.

Christoph
So, I'm I doing something wrong by defining new properties on the prototype property in my short snippet?
John Leidegren
@John: yes, it's wrong - only function objects have a predefined `prototype` property, so your code will throw an error, eg 'obj.prototype is undefined' in FF
Christoph
I think this is what it means to have function objects as first-class citizens.
John Leidegren
I hate non standard things, especially in programming languages, why is there even a __proto__ when it's clearly not needed?
John Leidegren
A: 

When a constructor creates an object, that object implicitly references the constructor’s “prototype” property for the purpose of resolving property references. The constructor’s “prototype” property can be referenced by the program expression constructor.prototype, and properties added to an object’s prototype are shared, through inheritance, by all objects sharing the prototype.

Tom