54

What is prototype property, and why is it necessary? So far, I have learnt that this provides public access to more intrinsic, and private prototype of the object; is that correct?

Also, what's the difference between following statements?

MyConstructor.age = 30;
MyConstructor.prototype.age = 30;

In short, I need a better understanding of keyword prototype.

Thanks

Tintin
  • 2,853
  • 6
  • 42
  • 74
  • 6
    You need to take your time to learn more about JavaScript. http://www.youtube.com/watch?v=v2ifWcnQs6M – Šime Vidas Aug 21 '12 at 22:47
  • 1
    Check this: http://stackoverflow.com/questions/572897/how-does-javascript-prototype-work – Claudi Aug 21 '12 at 22:48
  • 1
    this has been bothering me...i love this question – Muhammad Umer Apr 05 '13 at 02:51
  • 3
    So can anybody explain why you there are two ways to create new properties i.e."You can add new properties to an existing object by simply giving it a value" person.age=30; and person.prototype.age = 30; does the same thing what is the difference – Muhammad Umer Apr 05 '13 at 03:01
  • ok i got it: (let me know right or wrong) with person.age you need the object to be created already...and with person.prototype.age this will be added in the class and every object that uses that class. – Muhammad Umer Apr 05 '13 at 03:04
  • 8
    Sime: he is trying to learn more about JS, that's why he (and I) are here. Not everyone learns well from videos (I certainly don't!) – araneae Jun 03 '14 at 13:19
  • Possible duplicate of [What’s the purpose of prototype?](https://stackoverflow.com/questions/8433459/what-s-the-purpose-of-prototype) – Rohit Sharma Sep 20 '18 at 11:11

3 Answers3

68

"Prototype" is something that plays a role in objects.

In Javascript, everything is an object. Every object has a kind, and thus inherits the prototype of that kind.

For example, take a simple array: var a = []. You can make operations with it, like a.push(10). Where does this push method come from? From the prototype of Array object, which a is.

You can add your own methods to Array objects just by defining them in the prototype object. For example:

Array.prototype.sortNum = function() {this.sort(function(a, b) {return a - b});};

This way you can do something like a.sortNum() with all arrays, even the ones created before you defined the sortNum method.

(Note: for compatibility reasons, it's usually not recommended to extend the prototype of native objects like Arrays. But this particular example is usually a welcome addition, as well as normalizing methods like map and forEach for older browsers.)

(Just never ever extend Object.prototype! Unless you don't care to mess up for...in statements, the in operator and these sort of cases.)

If you want to define your own classes, like the name MyConstructor suggests, you'll have to define its prototype to define the methods for all the instances of that class:

function MyConstructor(name) {this.name = name};
MyConstructor.prototype = {
    print: function() {return this.name;}
};

var mc = new MyConstructor("foo");
alert(mc.print()); // alerts "foo"

You can define more than just functions in prototypes, too:

MyConstructor.prototype.age = 30;

alert(mc.age); // alerts 30

Watch out when you do this to define "default" object values, because changing it may cause a change in all instances of that class.

But this comes handy with Object.defineProperty:

Object.defineProperty(MyConstructor.prototype, "wholeString", {
    get: function() {return this.name + "=" + this.age;},
    set: function(v) {this.name = v.substring(3);}
});

alert(mc.wholeString); // alerts "foo = 30"

(Unfortunately, IE<9 allows this only for DOM objects...)

When you define MyConstructor.age = 30 instead, what you're actually doing is defining a member of the function MyConstructor, so mc.age would be undefined. Every instance of MyConstructor inherits the methods and members defined in MyConstructor.prototype, not the ones of the function MyConstructor.

There's much more to say, actually. Objects can be of a subclass of another class, thus inheriting the prototype of the superclass, too. For example, document.body is an instance of HTMLBodyElement, which is a subclass of HTMLElement, which is a subclass of Element and so on, until you get Object as the upmost superclass. So, document.body inherits all the methods defined in the prototype of HTMLBodyElement, HTMLElement, Element and Object. This is called the prototype chain.

Doing the same with custom objects is a bit tricky:

function Class() {};
Class.prototype.foo = function() {alert("foo");};

function Subclass() {};
Subclass.prototype = new Class();
Subclass.prototype.bar = function() {alert("bar");};

var a = new Class(), b = new Subclass();
a.foo(); // alerts"foo"
a.bar(); // throws an error
b.foo(); // alerts "foo"
b.bar(); // alerts "bar"

a instanceof Class;    // true
a instanceof Subclass; // false
b instanceof Class;    // true
b instanceof Subclass; // true
JJJ
  • 32,902
  • 20
  • 89
  • 102
MaxArt
  • 22,200
  • 10
  • 82
  • 81
  • awesome explantion... could you guide me to an exhaustive tutorial on object oriented javascript - I would be eventually using it to generate the html5 controls (and extended ones) at run time for my work... the tuorials by Douglas Crockford are really not that that conceptive and the slides by E John also lack explanation... thanks... – Tintin Aug 22 '12 at 00:40
  • @user503510 Gee, Crockford and Resig are two of the main Javascript gurus. Every Javascript programmer has learnt something from them. You can try the [MDN article](https://developer.mozilla.org/en-US/docs/JavaScript/Introduction_to_Object-Oriented_JavaScript?redirectlocale=en-US) about OOP programming or the one from [JavascriptKit](http://www.javascriptkit.com/javatutors/oopjs.shtml). – MaxArt Aug 22 '12 at 10:05
6

In JavaScript, function objects have a built-in .prototype property. The value of this property is an object. If the function is used as a constructor, the resulting instances inherit from that "prototype" object.

Example:

var Dog = function () {}; // the constructor function

Dog.prototype.bark = function () {}; // adding a method to Dog.prototype

var dog1 = new Dog; // creating a new instance

dog1.bark(); // the instance inherits the "bark" method from Dog.prototype

Note that the .prototype property (of function objects) is not the same as the [[Prototype]] internal property. All objects contain the latter. It's an internal reference to an object's prototype. (In the above example, the dog1 object's [[Prototype]] refers to Dog.prototype.) On the other hand, only function objects have a built-in .prototype property (which makes sense since only function objects can be used as constructors).

Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
4
var foo = function () {};
foo.bar = 5;
foo.prototype.foobar = 10;

var x = new foo();
x.bar; // undefined
x.foobar; // 10

Edit: Also, you can then do

foo.prototype.foobar = 20;
x.foobar; // 20
Paul S.
  • 64,864
  • 9
  • 122
  • 138