views:

99

answers:

2

What is a prototype for a javascript class? In other words, what is the different between

Example.prototype.method {}

and

Example.method{}

when defining the Example class?

edit: for those interested, i found a great explanation (in addition to the answer below) here for the difference between class methods and constructor methods: http://idhana.com/2009/07/13/constructor-vs-class-methods-in-javascript/

edit 2: The full answer! http://blog.anselmbradford.com/2009/04/09/object-oriented-javascript-tip-creating-static-methods-instance-methods/

+2  A: 

A prototype is like a Class definition, but it can be changed dynamically. Whenever you instantiate an object of a certain type, it uses the prototype as the template.

If you change a prototype, objects of that type will have those changes.

Matt
+5  A: 

The difference is in the latter example you're creating a static method, which is not inherited if Example is a constructor function. By defining properties in the prototype property of a constructor function and creating objects with the new keyword, the newly created objects inherit the prototype of the constructor and thus have access to those methods.

An example would be the methods defined in the built-in core constructors, such as String.. newly created strings have a indexOf method because there was one defined in the String function constructor's prototype

typeof String.prototype.indexOf // 'function'

var name = 'John';
alert( name.indexOf('J') ) // 0

The code below creates a function constructor, we first define a static method, create an object, find out the object does not have a getName method, then we define one in the prototype and find that now the object does have a getName method.

function Name(name) {
    this.name = name;
};
Name.getName = function(){};

var john = new Name();
typeof john.getName // undefined

var john = new Name();
Name.prototype.getName = function(){ alert( this.name )};
typeof john.getName

john.constructor.prototype.getName == john.getName // true

So to reiterate, inheritance in ECMAScript is achieved primarily by defining properties/methods in the prototype of a function constructor, example would be all the core constructors such as Date/Number/String which have methods defined in their respective prototype properties, which allows you to use those methods when you create an instance with the new keyword.

Remember that the newly created object has a constructor property which points to the constructor which made it, and we can access the prototype property directly. The john object we created does not directly own the getName method, since the interpreter cannot find it directly on the object it travels upwards to the constructor and finds it in its prototype.

And btw, we didn't really have to create a new instance of the john object, as pointed in the other answer you can define properties in the prototype after you create the initial constructor, and all objects would inherit those prototypal properties even after they've been created.

A static method cannot rely on context, can't rely on a specific instance of a class, can't rely on the this keyword therefore this would not be a static method:

function Name(name) {
    this.name = name;
    this.getName = function() { return this.name; }
};

This would be an example of a static method:

Name.getName = function() {};

but there's absolutely no sense in making getName static because as the name implies it must rely on an object instance to determine what the name property is, you should have more generic helper functions like parsing functions such as Date.parse as static methods and define instance methods in the prototype as they're more efficient than defining this.foo = function(){} in the constructor.

meder
so when would I want to use Name.getName = function(){}?
hatorade
or rather, when could i define methods (and how) for the Name class without using the prototype definition?
hatorade
`getName` would be a public method so you define it on the prototype rather than staticly, you would define a static method if there was no purpose to making it public or in the prototype.
meder
i guess my question is, how do you define a static method in the above example, and why would you want to do that rather than define an instance method?
hatorade
you defined it after the constructor was created, but said that it was undefined (line 7 of your second code chunk). so that would have worked had the function had stuff in it?
hatorade
basically, i'm confused because you say above when you defined the static method the new Name() you instantiated didn't get the method until you made it a prototype (instance) method. I'm wondering how to make it so that I could have used a static method instead and have the object be able to use that method. Code example would be great :)
hatorade
You could place generic helper functions that don't need context, real world example is `Date.parse`, `Date.parse('July 02 1988')` returns a timestamp and doesn't really require any context.
meder
never mind found my answer in this great example: http://idhana.com/2009/07/13/constructor-vs-class-methods-in-javascript/
hatorade
Actually I confused myself ( ha ), when I did `this.getName = function(){}` that wasn't an example of a static method since it does rely on the context of the object.
meder
ok so i didn't find my answer. i found the difference between constructor methods and prototype methods. but i guess i don't understand what the difference is between a static method and prototype/constructor methods. like, if i create a constructor, and define a static method outside of the constructor for that class, how do i use it and which objects get access to it?
hatorade
again, i just don't understand why this is true: typeof john.getName // undefined. how is it that the static method doesn't work? how WOULD we get it to work for Name?
hatorade
ahh, i get it! http://blog.anselmbradford.com/2009/04/09/object-oriented-javascript-tip-creating-static-methods-instance-methods/
hatorade