3

I am trying to understand Object-Oriented JavaScript and stuck with some examples. They seems kind of different conventional OOP.

First of all, are there any difference with those:

function Foo()
{
    this.bar = function ()
    {
        // ...
    };
}

vs.

function Foo() {}

Foo.prototype.bar = function()
{
    // ...
}

Also, should I use which one? Which one is proper way?


In another example for Factory Pattern.

function Circle()
{
    this.say = function() { console.log('I am circle.'); };
}

function Square()
{
    this.say = function() { console.log('I am square.'); };
}

function chooseShape(decision)
{
    var shape = null;

    if (decision === "Circle")
    {
        shape = Circle; // or Circle.prototype.constructor;
    } else if (decision === "Square")
    {
        shape = Square; // or Square.prototype.constructor;
    }

    return new shape();
}

If I change those lines with these:

if (decision === "Circle")
{
    shape = Circle.prototype.constructor;
} else if (decision === "Square")
{
    shape = Square.prototype.constructor;
}

They are works as expected but I wonder what is going on under the hood.

Kutsan Kaplan
  • 1,755
  • 3
  • 14
  • 22
  • 3
    Your first question (you've asked two), is covered by [Use of 'prototype' vs. 'this' in JavaScript?](http://stackoverflow.com/questions/310870/use-of-prototype-vs-this-in-javascript) – James Thorpe Sep 21 '16 at 14:37
  • 1
    Nothing much is going on under the hood. Constructor's prototype has a constructor property which points to the constructor function itself. Get [this](http://3.bp.blogspot.com/-dNrU3kSRcss/UGtAqJIOcAI/AAAAAAAAAfA/ShYVV1Yap_U/s1600/Javascript+Prototypal+Inheritance+Diagram+-+grand+picture+-+with+some+Dog+objects+-+and+Function+object.png) printed and stick on the wall. – Redu Sep 21 '16 at 14:50

4 Answers4

2

Functions on the prototype are only created once and shared between each instance. Functions created in the constructor are created as new objects for each new object created with the constructor.

As a general rule functions should be on the prototype since they will generally not be modified for different objects of the same type, and this has a slight memory/performance benefit. Other properties like objects and arrays should be defined in the constructor, unless you want to create a shared, static property, in which case you should use the prototype.

Hope this answers your question

g.005
  • 396
  • 1
  • 12
1

Those examples can explain the difference:

// constructor function
function Person(first, last) {
    this.firstName = first;
    this.lastName = last;

    this.hey = function() { ... }
}

var person1 = new Person("Frank", "Sinatra")

// add a method to each person instance
Person.prototype.name = function() {
    return this.firstName + " " + this.lastName
};

person1.name() // "Frank Sinatra"

Prototype allows you to add new properties to constructor functions and their instances.

Another difference is that Prototype is defined on class level and the properties in the constructor are on instance level. So name() will be defined only once, while this.hey will be defined for every instance.

Lyubomir
  • 19,615
  • 6
  • 55
  • 69
0

1. In the first case, you create new function each time you create a new object and put this function into property of object. In second case, you create function just once and put it into prototype.

Both of the cases will result in method bar being callable on each instance of Foo. The "proper way" is to put method definitions in prototype (i.e. second case); but if there is some instance-specific variables you don't want to put in instance object, you may create a function every time object is created. But keep in mind that it will cost you more memory.

2. There is no difference. Circle and Square should be pointing at same functions as Circle.prototype.constructor and Square.prototype.constructor. You can see it by yourself:

> Circle.prototype.constructor === Circle
< true
Nartallax
  • 123
  • 6
-1

The first way to create an instance of Foo is by using the function constructor and calling new:

function Foo()
{
    this.bar = function ()
    {
        // ...
    };
}

If you create an instance of Foo by calling the new operator as follow:

var foo= new Foo();

then for every object created like so will have a new bar method created.

Alternatively, using the prototype property, all Foo objects created will not have a separate bar method created. Instead they will all inherit bar from the prototype. Because there will be only one copy of bar now, obviously this way is more memory efficient.

Kevin Le - Khnle
  • 10,579
  • 11
  • 54
  • 80