Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are prototypes in JavaScript?

What is a prototype for a JavaScript class? In other words, what is the difference 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/

like image 654
Tony Stark Avatar asked Nov 20 '09 03:11

Tony Stark


2 Answers

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.

like image 120
meder omuraliev Avatar answered Sep 19 '22 22:09

meder omuraliev


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.

like image 34
Matt H Avatar answered Sep 19 '22 22:09

Matt H