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
Whenever we create a JavaScript function, JavaScript adds a prototype property to that function. A prototype is an object, where it can add new variables and methods to the existing object. i.e., Prototype is a base class for all the objects, and it helps us to achieve the inheritance.
prototype is a property of a Function object. It is the prototype of objects constructed by that function. __proto__ is an internal property of an object, pointing to its prototype.
Each object has a private property which holds a link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype. By definition, null has no prototype, and acts as the final link in this prototype chain.
The prototype attribute is set when an object is created. Recall from Prototypes that objects created from object literals use Object. prototype as their prototype. Objects created with new use the value of the prototype property of their constructor function as their prototype.
"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
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With