Trying to understand the difference between prototype and constructor in JavaScript

javascript, prototype

Solution

It is pretty hard to wrap your mind around this concept 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 or 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 an 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 don't do that, because we need to do wholly different things with the new classes that 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 OOO this would be the desired end result `class Title extends Foo(){}`. So lets take a look at 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 can't 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 initialize the `Foo` object in the `Titl`e 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`.

Problem

I'm new to JavaScript and trying to understand this concept. I have read many articles regarding prototypes and constructors but wherever I go I'm left with confusion. The confusion arises when people talk about constructors and prototypes 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 ``` prototype is a way that JS achieves inheritance, since `Emp(name)` is the base function prototype is referenced to the same function itself. Is that what happened? In what way do `employee.constructor` and `employee.prototype.constructor` differ? Why was `jack.prototype` `undefined`? i.e. If it is inheriting from the function `Emp(name)` why didn't it reference that function? How can I clearly predict (without typing in the console) what the prototype or the constructor or the prototype.constructor ......yields?

Original source

Related problems