Prototype keyword in Javascript
html, javascript
Solution
"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 `Array`s. 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 `prototype`s, 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
Problem
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