Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prototype and constructor in JavaScript (plain English)?

"JavaScript is the worlds most misunderstood language" -D.Crockford

My questions:

  1. Constructor and prototypes in plain English?
  2. What is the need of using a prototype? What is the purpose behind using Prototypes and constructors? I mean do they provide more flexibility. I am asking this as I have been using this language for the past six months and never had a situation where I used prototypes and constructor.

I am not looking for any syntax and how to go about things explanations as I do understand some part of what they are, just wanted to know these things in a simpler way. An analogy (non-tech) or example would be great.*

Details why I asked this question (ignore if you want to):

I have been using JavaScript for the past six months and was shocked when I came to know that JavaScript is a prototype-based language.

I went through some Stack Overflow questions about how JavaScript was supposed to be used and came across prototypes and constructors.

I learned it, and now I can say that I am not a noob when it comes to constructors and prototypes. I am familiar with the syntax. But still I think I am missing something and haven't got down to the core of this language, and I do get confused sometimes.

I hope I am clear.

like image 213
HIRA THAKUR Avatar asked Aug 18 '13 11:08

HIRA THAKUR


1 Answers

Constructor and protoypes in plain English?

Constructor functions create objects and assign prototypes to them. A prototype is an object with various properties that an object can inherit through the prototype chain. As always, examples help:

function Foo() {
}
Foo.prototype.answer = 42;

var f = new Foo();
console.log(f.answer); // "42"

Foo is a constructor function. When you use new Foo, the object that Foo.prototype points to will become the prototype of the object that gets created. When you do f.answer, since f doesn't have its own property with the name answer, the JavaScript engine looks at f's prototype to see if it has one. Since it does, it uses the value from the prototype and we see "42" in the console. This is how properties are resolved: By looking at an object seeing if it has a property with the given name, and if not, going to its prototype to see if it has the property, and if not going to its prototype, and so on.

Note that a consequence of the above is that adding properties to a prototype after an object has been created using that prototype works just fine; you can use those new properties via the object:

function Foo() {
}
Foo.prototype.answer = 42;

var f = new Foo();
console.log(f.question); // "undefined", neither `f`, nor `Foo.prototype`, nor
                         // `Object.prototype` has a `question` property

Foo.prototype.question = "Life, the Universe, and Everything";
console.log(f.question); // "Life, the Universe, and Everything"

As of ES5, constructor functions are no longer the only way you can assign prototypes to objects. Now you can also do it via Object.create. The above is roughly equivalent to this:

var fooProto = {
    answer: 42
};
var f = Object.create(fooProto);
console.log(f.answer); // "42"

What is the purpose behind using Prototypes and constructors?

To share characteristics between objects. The properties of a prototype can be functions or data, both of which the objects using that prototype have access to and can reuse.

Re your comment below:

I understood the part about sharing characteristics, but could I get some more detailing in to it

Well, consider a Circle constructor:

function Circle(radius) {
    this.r = radius;
}
Circle.prototype.radius = function() {
    return this.r;
};
Circle.prototype.diameter = function() {
    return this.r * 2;
};
Circle.prototype.circumference = function() {
    return 2 * Math.PI * this.r;
};
Circle.prototype.area = function() {
    return Math.PI * this.r * this.r;
};

All objects constructed by Circle will get Circle.prototype as their prototype, and so they all have the handy diameter, circumference, et. al. functions.

var c1 = new Circle(3);
console.log(c1.area());          // 28.274333882308138
console.log(c1.circumference()); // 18.84955592153876

var c2 = new Circle(5);
console.log(c2.area());          // 78.53981633974483
console.log(c2.circumference()); // 31.41592653589793

They share those properties in a memory-efficient way: Each instance doesn't have its own copy of those properties (which would mean keeping each property name and its value in each obejct); instead, they just have a reference to their prototype, which they share, which has those properties.

like image 94
T.J. Crowder Avatar answered Sep 23 '22 07:09

T.J. Crowder