Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prototype keyword in Javascript

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

like image 635
Tintin Avatar asked Aug 21 '12 22:08

Tintin


People also ask

Why prototype is used in JavaScript?

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.

What is Proto and prototype in JavaScript?

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.

What is a prototype chain in JavaScript?

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.

What is prototype attribute in JavaScript?

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.


2 Answers

"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 
like image 189
MaxArt Avatar answered Sep 20 '22 23:09

MaxArt


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).

like image 27
Šime Vidas Avatar answered Sep 18 '22 23:09

Šime Vidas