Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to understand the difference between prototype and constructor in JavaScript

I'm new to JavaScript ,to understand this concept i have read many articles regarding prototype and constructors but where ever i go i'm left with confusion.

The confusion arises when people talk about constructor and prototype simultaneously.

In the following example

var employee = function Emp(name) {     this.name = name; } var jack = new employee("Jack Dwain");  employee.constructor //gives Function()  employee.prototype // gives  Emp {}  employee.prototype.constructor //gives Emp(name)  jack.constructor //gives Emp(name)  jack.prototype //gives undefined 
  1. prototype is a way JS achieves inheritance,since Emp(name) is the base function prototype is referenced to the same function itself. Is that what happened?

  2. In what way employee.constructor and employee.prototype.constructor differ?

  3. Why was jack.prototype is undefined i.e If it is inheriting from the function Emp(name) why it didn't reference that function?

  4. How can I clearly predict myself without typing in the console what the prototype or the constructor or the prototype.constructor ......yields

like image 697
Ein2012 Avatar asked Feb 19 '15 06:02

Ein2012


People also ask

What is the difference between constructor and prototype in JavaScript?

Short answer So what's the difference between constructor and prototype? A short answer is that the constructor is a function that is used to create an object, while the prototype is an object that contains properties and methods that are inherited by objects created from a constructor.

What is the difference between prototype and object in JavaScript?

Well not exactly. Prototypes are a special type of object and exist as a property on function-objects. When we try to access a key on a function-object, JavaScript will look at its prototype property to see if it's there. If not it will go up the prototype-chain to try to find it.

What does prototype mean in JavaScript?

The prototype is an object that is associated with every functions and objects by default in JavaScript, where function's prototype property is accessible and modifiable and object's prototype property (aka attribute) is not visible. Every function includes prototype object by default.

What is the difference between constructor and object in JavaScript?

A constructor is a function that creates and initializes an object. JavaScript provides a special constructor function called Object() to build the object. The return value of the Object() constructor is assigned to a variable. The variable contains a reference to the new object.


2 Answers

Its a pretty hard thing to wrap your mind around if you are used to the ease of extending objects in other OOP languages, but I'll do my best to explain the uses of those and what is what. I am going to assume you are familiar with other OOP languages. Correct me if I'm wrong.

All functions have the prototype Function(). They are inheriting all base functionality from Function like toString() and valueOf().

Then there is a constructor. That is what you use to initialize an object with.

p = new Foo();

So in this case we have two things.

  • A function Foo with Function as prototype(Foo)
  • A Function object with Foo() as constructor(p)

(following me yet?)

The Foo() constructor can override some base functionality of the Function constructor, but also leave it as it is and make good use of it.

If you are familiar with OOP principles, The prototype is the base class, the constructor your current class. in OOP the above would be class Foo extends Function

You can also start inheritance with this entire setup of prototype and constructor making more complex objects as you go whilst sharing functionality.

For example this:

// make a object initialiser extending Function. in oop `class Foo extends Function`  function Foo(bar) {     this.baz = bar; } Foo.prototype.append = function(what) {     this.baz += " " + what; }; Foo.prototype.get() {     return this.baz } 

Now lets say we want different ways to get baz out of there. one for console logging and one for putting it on the title bar. We could make a big thing about our class Foo, but we dont do that, because we need to do wholly different things with the new classes but are made for different implementations. The only thing they need to share are the baz item and the setters and getters.

So we need to extend it to use an OOP term. in OOp this would be the desired end result class Title extends Foo(){}. So lets take a look how to get there.

function Title(what) {     this.message = what; } 

At this point the Title function looks like this:

  • prototype Function
  • constructor Title

So, to make it extends Foo we need to change the prototype.

Title.prototype = new Foo(); 
  • prototype Foo
  • constructor Foo

This is done by initializing a new Foo() object against the prototype. Now its basically a Foo object called Title. That is not what we want because now we cant access the message part in Title. We can make it properly extend Foo() by resetting the constructor to Title

Title.prototype.constructor = Title; 
  • prototype Foo
  • Constructor Title

Now we are faced with one more problem. The constructor of Foo doesn't get initialized so we end up with an undefined this.baz

To resolve that we need to call the parent. In java you would do that with super(vars), in php $parent->__construct($vars).

In javascript we have to modify the Title class constructor to call the constructor of the parent object.

So the Title class constructor would become

function Title(what) {     Foo.call(this,what);     this.message = what; } 

By using the Function object property Foo inherited we can initialism the Foo object in the Title object.

And now you have a properly inherited object.

So instead of using a keyword like extend like other OOP languages it uses prototype and constructor.

like image 71
Tschallacka Avatar answered Sep 22 '22 09:09

Tschallacka


If you want to create a javascript object you can simply declare a new object and give it properties (I've chosen to objectify myself):

var myself= {     name:"Niddro",     age:32 }; 

This method allows you to make one object. If what you want to have is a prototype describing a person in general, where you can declare several people with the same setup. To create a prototype, you can use a constructor, as seen below:

//Constructor function generalNameForObject(param1, param2,...) {     //Give the object some properties... } 

I have a prototype (a recipe) in mind that I want to call person and it should contain the properties name and age and I'll use a constructor to make it:

function person(name,age) {     this.name=name;     this.age=age; } 

The above construct function describes the prototype for my person objects.

Create a new person by calling the construct function:

var myself = new person("Niddro",31); var OP = new person("rajashekar thirumala",23); 

Some time passes and I realise that I've had a birthday so I need to change the property of the prototype:

myself.age=32; 

If you want to add properties to the construct, you need to manually add it into the construct function:

function person(name,age,rep) {     this.name=name;     this.age=age;     this.reputation=rep; } 

Instead, you can add properties to the prototype by doing the following (here "prototype" is an actual command and not just a name):

function person(name,age,rep) {     this.name=name;     this.age=age; } person.prototype.reputation=105; 

note that this will add a reputation of 105 for all objects created.

I hope this has given you some more insight on the relationship between the constructor and prototype.

like image 38
Niddro Avatar answered Sep 25 '22 09:09

Niddro