Constructor Function VS Factory Functions

Constructor function vs Factory functions

The basic difference is that a constructor function is used with the new keyword (which causes JavaScript to automatically create a new object, set this within the function to that object, and return the object):

var objFromConstructor = new ConstructorFunction();

A factory function is called like a "regular" function:

var objFromFactory = factoryFunction();

But for it to be considered a "factory" it would need to return a new instance of some object: you wouldn't call it a "factory" function if it just returned a boolean or something. This does not happen automatically like with new, but it does allow more flexibility for some cases.

In a really simple example the functions referenced above might look something like this:

function ConstructorFunction() {
this.someProp1 = "1";
this.someProp2 = "2";
}
ConstructorFunction.prototype.someMethod = function() { /* whatever */ };

function factoryFunction() {
var obj = {
someProp1 : "1",
someProp2 : "2",
someMethod: function() { /* whatever */ }
};
// other code to manipulate obj in some way here
return obj;
}

Of course you can make factory functions much more complicated than that simple example.

One advantage to factory functions is when the object to be returned could be of several different types depending on some parameter.

what is the difference and what is better to use: Factory Function vs Constructor Function. Please reason your approach, so I can learn

For most circumstances I'd say the constructor function is better.

  • It lets you check whether the object is a Circle by using the instanceof operator (i.e. circle instanceof Circle)
  • It makes the code more readable - when someone sees new Circle they know that a class is being instantiated, and they know that it will have a predictable behaviour, whereas for the first case they need to check the function definition (or documentation) of createCircle before they know anything about what this function is returning.
  • You can optimise the constructor a little more - if you define the draw function on the class's prototype (i.e. Circle.prototype.draw = function(){/*etc*/}) then it doesn't get declared each time you call new Circle.

That said, if you're creating an object with just a few properties and no methods then using the first example is perfectly reasonable.

Clarification need in class vs constructor function vs factory function

Since it returns an object its a factory function - it's already explained there.

Constuctor functions behaviour different from this, it doesn't return value:

function Person(name, age, location, occupation){
this.name = name
this.age = age
this.location = location
this.occupation = occupation
}

Person.prototype.printDetails = function(){
console.log(`My name is ${this.name} and I'm ${this.age} years old. I live in ${this.location} and I work as a ${this.occupation}.`);
};

const secondUser = new Person('Johnny', 25, 'London', 'Driver');
secondUser.printDetails();

I used definition of methods by extending prototype just to separate constructor function, and you can still define a methods inside constructor function as well:

function Person(name, age, location, occupation){
this.name = name
this.age = age
this.location = location
this.occupation = occupation

this.printDetails = function(){
console.log(`My name is ${this.name} and I'm ${this.age} years old. I live in ${this.location} and I work as a ${this.occupation}.`);
};
}

const secondUser = new Person('Johnny', 25, 'London', 'Driver');
secondUser.printDetails();

Constructors vs Factory Methods

From page 108 of Design Patterns: Elements of Reusable Object-Oriented Software by Gamma, Helm, Johnson, and Vlissides.

Use the Factory Method pattern when

  • a class can't anticipate the class of objects it must create
  • a class wants its subclasses to specify the objects it creates
  • classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate

Constructor Function vs Factory Function in regards of creating a getter

With a real constructor function you have to use defineProperty:

  function ConstructorFunctionCircle(radius) {
this.radius = radius;
Object.defineProperty(this, "area", {
get: function() {
return radius * 20;
}
});
}

However I would prefer a class instead:

  class Circle {
constructor(radius) {
this.radius = radius;
}
get area() {
return 2 * Math.PI * this.radius ** 2;
}
}

Factory pattern vs constructor pattern in javascript

Factories create an object and returns it. That is about it. The object that is created stands alone and the best part about this is you can use that object and not be effected by what happens to the other objects. This is know as a singleton.

var Car = function(){
var car = {};
car.running = false;
car.toggleEngine = function(){
this.running = !this.running;
}
return car;
};

car1 = Car(); // running false
car2 = Car(); // running false
car1.toggleEngine(); // running true
car2.toggleEngine = undefined; // to broke down.
car1.toggleEngine(); //running false

Constructors add code to the function so you have a link to the prototype of the object constructor. The nice part about this additional link is to use the functional shared technique which looks like this.

var Car = function (){
this.running = false;
};
Car.prototype.toggleEngine = function(){
this.running = !this.running;
}
var car1 = new Car; //running false
var car2 = new Car; //running false

car2.toggleEngine() //running true
Car.prototype.toggleEngine = function(){};
car1.toggleEngine() //running false

As we can see after the objects were created they still were very much linked together.

To be clear you can still do the following and not effect the objects created by the constructor. With functional shared method and mask the prototype function given by the constructor. So there are not fully linked but they are linked through the constructors prototype.

var car1 = new Car; //running false
var car2 = new Car; //running false

car2.toggleEngine() //running true
car2.toggleEngine = function(){};
car1.toggleEngine() //running true

What is the difference between module and factory function?

The main difference between modules and factory functions are simpler than you think.

Modules are just files with blocks of code that you can import/export.

Whereas factory functions are functions that create objects and return them. Also you might find this other stack overflow post that explains constructor functions vs factory functions:

Constructor function vs Factory functions

Object oriented javascript with prototypes vs closures

The second one doesn't really create an instance, it simply returns an object. That means you can't take advantage of operators like instanceof. Eg. with the first case you can do if (myBook instanceof Book) to check if the variable is a type of Book, while with the second example this would fail.

If you want to specify your object methods in the constructor, this is the proper way to do it:

function Book(title) {
this.title = title;

this.getTitle = function () {
return this.title;
};
}

var myBook = new Book('War and Peace');
alert(myBook.getTitle())

While in this example the both behave the exact same way, there are differences. With closure-based implementation you can have private variables and methods (just don't expose them in the this object). So you can do something such as:

function Book(title) {
var title_;

this.getTitle = function() {
return title_;
};

this.setTitle = function(title) {
title_ = title;
};

// should use the setter in case it does something else than just assign
this.setTitle(title);
}

Code outside of the Book function can not access the member variable directly, they have to use the accessors.

Other big difference is performance; Prototype based classing is usually much faster, due to some overhead included in using closures. You can read about the performance differences in this article: http://blogs.msdn.com/b/kristoffer/archive/2007/02/13/javascript-prototype-versus-closure-execution-speed.aspx



Related Topics



Leave a reply



Submit