I'm slightly unclear what you mean by "factory function" — whether you mean a traditional JavaScript constructor function that gets called as new Person(), or a function that returns an object (literal?) that gets called as Person. If the former, I'll address it below. If the latter, then read on. Either way, I think the big reason to recommend classes is that they probably do the right thing with less syntactic noise. Classes vs Factories Consider a factory function like export function Person(name, age, gender) { return { name, age, gender }; } (using the newer shorthand object notation). So we can instantiate an object as let alice = Person('Alice', 44, 'female'); For one, we can't use instanceof. alice instanceof Person // false Small, but that's one difference — there's nothing tying the values back to the factory. But now consider if we wanted to include a method in our object, e.g., format to print a description of the person. We might be tempted to say export function Person(name, age, gender) { return { name, age, gender, format() { return `${this.name} is ${this.age} years old and ${this.gender}.` } }; } This will function correctly, but there's a problem. let alice = Person('Alice', 44, 'female'); let bob = Person('Bob', 44, 'male'); alice.format === bob.format // false They have different function instances for their format methods — in fact every object returned by Person will have a fresh function created for format. Those are a complete waste of memory, because we could use a single function instance for all of them. But it's messier to say. function format() { return `${this.name} is ${this.age} years old and ${this.gender}.` } export function Person(name, age, gender) { return { name, age, gender, format }; } We need to create a single format function that we keep module-private, and include it in each person. That's annoying, and the definition of Person is spreading out. Classes do the right thing here automatically. So we could declare export class Person { constructor(name, age, gender) { this.name = name; this.age = age; this.gender = gender; } format() { return `${this.name} is ${this.age} years old and ${this.gender}.` } } and then let alice = Person('Alice', 44, 'female'); let bob = Person('Bob', 44, 'male'); alice.format === bob.format // true Classes vs Constructors In the end, classes are pretty much just syntactic sugar over prototypes and constructors, so they can do the same things. However, constructors have the same problem as factories — the definition gets spread around. To declare a method with a constructor function you have to patch the constructor after declaring it. export function Person(name, age, gender) { this.name = name; this.age = age; this.gender = gender; } Person.prototype.format() { return `${this.name} is ${this.age} years old and ${this.gender}.` } Once again, classes do the same thing in one declaration with less noise. My Preference: Classes and Factories My preference is often to have a class to define the data type — e.g., the Person class above. Then I'll create factory functions for various use cases in the application. So maybe I'd have export function createBlankPerson() { return new Person('', 0, 'unknown'); } export function createRandomPerson() { return new Person( SAMPLE_NAMES[randomInt(0, SAMPLE_NAMES.length)], randomInt(18, 100), SAMPLE_GENDERS[randomInt(0, SAMPLE_GENDERS.length)] ); } This way I have the Person class to define the shape and methods; it's constructor to create instances from name, age, and gender; and the convenient factory methods more more specific use-cases. Answer from javajunkie314 on reddit.com
🌐
Reddit
reddit.com › r/javascript › [askjs] is there any reason to use a class over a factory function?
r/javascript on Reddit: [AskJS] Is there any reason to use a class over a factory function?
November 10, 2022 -

Lets say I want to create an object that represents a person with the properties name, age, and gender.

Is there any objective reason I should use a class to represent this rather than just making a function `Person()` which creates the object?

Top answer
1 of 13
178
I'm slightly unclear what you mean by "factory function" — whether you mean a traditional JavaScript constructor function that gets called as new Person(), or a function that returns an object (literal?) that gets called as Person. If the former, I'll address it below. If the latter, then read on. Either way, I think the big reason to recommend classes is that they probably do the right thing with less syntactic noise. Classes vs Factories Consider a factory function like export function Person(name, age, gender) { return { name, age, gender }; } (using the newer shorthand object notation). So we can instantiate an object as let alice = Person('Alice', 44, 'female'); For one, we can't use instanceof. alice instanceof Person // false Small, but that's one difference — there's nothing tying the values back to the factory. But now consider if we wanted to include a method in our object, e.g., format to print a description of the person. We might be tempted to say export function Person(name, age, gender) { return { name, age, gender, format() { return `${this.name} is ${this.age} years old and ${this.gender}.` } }; } This will function correctly, but there's a problem. let alice = Person('Alice', 44, 'female'); let bob = Person('Bob', 44, 'male'); alice.format === bob.format // false They have different function instances for their format methods — in fact every object returned by Person will have a fresh function created for format. Those are a complete waste of memory, because we could use a single function instance for all of them. But it's messier to say. function format() { return `${this.name} is ${this.age} years old and ${this.gender}.` } export function Person(name, age, gender) { return { name, age, gender, format }; } We need to create a single format function that we keep module-private, and include it in each person. That's annoying, and the definition of Person is spreading out. Classes do the right thing here automatically. So we could declare export class Person { constructor(name, age, gender) { this.name = name; this.age = age; this.gender = gender; } format() { return `${this.name} is ${this.age} years old and ${this.gender}.` } } and then let alice = Person('Alice', 44, 'female'); let bob = Person('Bob', 44, 'male'); alice.format === bob.format // true Classes vs Constructors In the end, classes are pretty much just syntactic sugar over prototypes and constructors, so they can do the same things. However, constructors have the same problem as factories — the definition gets spread around. To declare a method with a constructor function you have to patch the constructor after declaring it. export function Person(name, age, gender) { this.name = name; this.age = age; this.gender = gender; } Person.prototype.format() { return `${this.name} is ${this.age} years old and ${this.gender}.` } Once again, classes do the same thing in one declaration with less noise. My Preference: Classes and Factories My preference is often to have a class to define the data type — e.g., the Person class above. Then I'll create factory functions for various use cases in the application. So maybe I'd have export function createBlankPerson() { return new Person('', 0, 'unknown'); } export function createRandomPerson() { return new Person( SAMPLE_NAMES[randomInt(0, SAMPLE_NAMES.length)], randomInt(18, 100), SAMPLE_GENDERS[randomInt(0, SAMPLE_GENDERS.length)] ); } This way I have the Person class to define the shape and methods; it's constructor to create instances from name, age, and gender; and the convenient factory methods more more specific use-cases.
2 of 13
9
Class offers syntax sugar over construction and inheritance. It is never necessary, but can be useful in some contexts like building a library. The console will log things with their class name instead of just object and you can use instanceof to do some type checking with classes.
🌐
DEV Community
dev.to › snevy1 › classes-vs-factory-functions-in-javascript-4fjn
Classes vs Factory functions in Javascript - DEV Community
November 30, 2023 - In my previous article, I discussed ... you know constructors then classes shouldn't be hard to grasp. Classes are a syntactic sugar of constructors in Javascript....
Top answer
1 of 8
190

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.

2 of 8
141

Benefits of using constructors

  • Most books teach you to use constructors and new

  • this refers to the new object

  • Some people like the way var myFoo = new Foo(); reads.

Drawbacks

  • Details of instantiation get leaked into the calling API (via the new requirement), so all callers are tightly coupled to the constructor implementation. If you ever need the additional flexibility of the factory, you'll have to refactor all callers (admittedly the exceptional case, rather than the rule).

  • Forgetting new is such a common bug, you should strongly consider adding a boilerplate check to ensure that the constructor is called correctly ( if (!(this instanceof Foo)) { return new Foo() } ). EDIT: Since ES6 (ES2015) you can't forget new with a class constructor, or the constructor will throw an error.

  • If you do the instanceof check, it leaves ambiguity as to whether or not new is required. In my opinion, it shouldn't be. You've effectively short circuited the new requirement, which means you could erase drawback #1. But then you've just got a factory function in all but name, with additional boilerplate, a capital letter, and less flexible this context.

Constructors break the Open / Closed Principle

But my main concern is that it violates the open/closed principle. You start out exporting a constructor, users start using the constructor, then down the road you realize you need the flexibility of a factory, instead (for instance, to switch the implementation to use object pools, or to instantiate across execution contexts, or to have more inheritance flexibility using prototypal OO).

You're stuck, though. You can't make the change without breaking all the code that calls your constructor with new. You can't switch to using object pools for performance gains, for instance.

Also, using constructors gives you a deceptive instanceof that doesn't work across execution contexts, and doesn't work if your constructor prototype gets swapped out. It will also fail if you start out returning this from your constructor, and then switch to exporting an arbitrary object, which you'd have to do to enable factory-like behavior in your constructor.

Benefits of using factories

  • Less code - no boilerplate required.

  • You can return any arbitrary object, and use any arbitrary prototype - giving you more flexibility to create various types of objects which implement the same API. For example, a media player that can create instances of both HTML5 and flash players, or an event library which can emit DOM events or web socket events. Factories can also instantiate objects across execution contexts, take advantage of object pools, and allow for more flexible prototypal inheritance models.

  • You'd never have a need to convert from a factory to a constructor, so refactoring will never be an issue.

  • No ambiguity about using new. Don't. (It will make this behave badly, see next point).

  • this behaves as it normally would - so you can use it to access the parent object (for example, inside player.create(), this refers to player, just like any other method invocation would. call and apply also reassign this, as expected. If you store prototypes on the parent object, that can be a great way to dynamically swap out functionality, and enable very flexible polymorphism for your object instantiation.

  • No ambiguity about whether or not to capitalize. Don't. Lint tools will complain, and then you'll be tempted to try to use new, and then you'll undo the benefit described above.

  • Some people like the way var myFoo = foo(); or var myFoo = foo.create(); reads.

Drawbacks

  • new doesn't behave as expected (see above). Solution: don't use it.

  • this doesn't refer to the new object (instead, if the constructor is invoked with dot notation or square bracket notation, e.g. foo.bar() - this refers to foo - just like every other JavaScript method -- see benefits).

🌐
Medium
sayansingha.medium.com › factory-functions-vs-classes-javascript-4c550dad1966
Factory Functions vs Classes: JavaScript | by Sayan Singha(@dvlpr_ind) | Medium
April 30, 2021 - In my opinion and experience, factory function and functional programming as a whole is far more convenient, easy to maintain, easy to refactor and debug, with much less downside of performance issue.
🌐
Codecademy Forums
discuss.codecademy.com › get help › javascript
Is there still a purpose to factory functions or should we always use classes? - JavaScript - Codecademy Forums
April 17, 2019 - Hello! I am wondering if classes make the ‘factory functions’ we learned during the objects lesson obsolete? Is there a time where it is more appropriate to use a factory function? Or should we generally always use classes to build multiple objects?
🌐
freeCodeCamp
freecodecamp.org › news › class-vs-factory-function-exploring-the-way-forward-73258b6a8d15
Class vs Factory function: exploring the way forward
March 25, 2018 - Take the example of a global object that can be modified directly from the Developer Console. When using factory function, only the methods we expose are public, everything else is encapsulated.
🌐
JavaScript Tutorial
javascripttutorial.net › home › javascript tutorial › javascript factory functions
JavaScript Factory Functions
October 6, 2023 - let person1 = createPerson('John', 'Doe'); let person2 = createPerson('Jane', 'Doe'); console.log(person1.getFullName()); console.log(person2.getFullName()); Code language: JavaScript (javascript) The code works perfectly fine. However, in practice, you will rarely use the factory functions. Instead, you use classes or constructor/prototype patterns.
Find elsewhere
🌐
YouTube
youtube.com › watch
Factory Function vs. Constructor vs. Class - JavaScript Tutorial - YouTube
The JavaScript Tool I'm using to demonstrate:https://runjs.app/ColorCodeColorCode Etsy Merchandise store:https://www.etsy.com/shop/ColorCodeStoreWhat is the ...
Published   May 21, 2021
🌐
Program With Jayanth
programwithjayanth.com › interviews › javascript › factory-functions-and-classes-in-javascript
Factory Functions and Classes in JavaScript | Program With Jayanth
March 7, 2024 - In JavaScript, both factory functions and classes provide ways to create and manage objects, but they do so using different approaches and philosophies. Factory Functions: A factory function is simply a function that returns a new object. Factory ...
🌐
Reddit
reddit.com › r/javascript › [askjs] factory functions vs. constructors. why choose factory functions?
r/javascript on Reddit: [AskJS] Factory functions vs. Constructors. Why choose factory functions?
March 13, 2024 -

Hi, from my limited understanding of both concepts there are two big differences between the two. Firstly, constructors create a prototype and factory functions don't. Secondly, factory functions return an object(which can include functions). so if we return functions that reference variables we don't want a user to directly access we effectively create a private variable(using closure). However I just discovered that constructors can have private variables by defining variables without the "this" keyword. So my question is as follows: Why would someone choose factory functions over constructors? I can't see a valid reason for wanting to avoid prototypal inheritance since it can provide extra behaviour when needed and constructors can implement private variables as well.

🌐
GeeksforGeeks
geeksforgeeks.org › what-are-factory-functions-in-javascript
What are factory functions in JavaScript ? | GeeksforGeeks
January 9, 2024 - In Angular, the factory function is always inclined towards class and constructors. Generally, the factory function is used to provide service as a dependency in any angular application.
🌐
DEV Community
dev.to › parenttobias › factories-and-closures-or-classes-and-constructors-does-it-matter-8p0
Factories and Closures, or Classes and Constructors... Does It Matter? - DEV Community
June 12, 2022 - Everything else, as this is a class, is in the prototype. That's the significant difference between the two: the factory-based object is composed of all its functionality, while the class-based object inherits it from the class.
🌐
JavaScript in Plain English
javascript.plainenglish.io › why-factories-are-better-than-classes-in-javascript-1248b600b6d4
Why Factories are better than Classes in JavaScript | by GreekDataGuy | JavaScript in Plain English
June 13, 2023 - As a backend developer forced to ... simple, and a basic understanding will save you headaches. In a nutshell, a factory is a function that returns an object, while a class is a template for an object....
🌐
Bomberbot
bomberbot.com › javascript › class-vs-factory-function-exploring-the-way-forward
Class vs Factory Function: Exploring the Way Forward - Bomberbot
The only difference is that factory functions are callable directly, while classes need to be instantiated with new. Since the introduction of class syntax in ES6, they‘ve seen significant adoption in the JavaScript ecosystem.
🌐
The Odin Project
theodinproject.com › lessons › node-path-javascript-factory-functions-and-the-module-pattern
Factory Functions and the Module Pattern | The Odin Project
We can make use of this in factory functions, coming up shortly. The biggest problem with constructors is that they don’t provide automatic safeguards that prevent from using them wrong. One of the key arguments is how they look like regular JavaScript functions, even though they do not behave like regular functions.
Top answer
1 of 3
7

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();
2 of 3
4

Javascript takes its roots in Prototypal Inheritance:

// Prototype
var ProtoCtr = function ProtoCtr(name, age) {
    this.name = name;
    this.age = age;
};
ProtoCtr.prototype.printDetails = function printDetails() { console.log(`Hi, I'm ${this.name} and I'm ${this.age} years old`); };

var protoInstance = new ProtoCtr('John', 21);
protoInstance.printDetails();

In short:

  • Functions expose prototypes

  • Defines a this context referring to the instance

  • Use the new keyword to create an instance

Then, with ES6, the language offered the possibility to use the class keyword (to please classical OO developers). It's a syntax which allow to group the declaration of your object in a block, avoiding to extend the prototype "manually". Under the hood, it does the exact same thing than the prototypal model, it's just an other way to write it.

// Class
class ClassCtr {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    printDetails() {
        console.log(`Hi, I'm ${this.name} and I'm ${this.age} years old`);
    }
}
var classInstance = new ClassCtr('John', 21);
classInstance.printDetails();

Key concepts are about the same, but you don't use prototype to expose methods to your instance but declare it directly inside the class block.

Then, there is the factory pattern, which is not a language specs but a pattern, a way to do things. It's my personal favorite. The factory function builds and return the instance. With this method, you get rid of the new keyword and don't need the this anymore to refer to you instance:

// Factory
var factoryCtr = function factoryCtr(name, age) {
    var instance = {
        name: name,
        age: age,
        printDetails: function printDetails() { console.log(`Hi, I'm ${instance.name} and I'm ${instance.age} years old`); }
    };
    return instance;
}
var factoryInstance = factoryCtr('John', 21);
factoryInstance.printDetails();

Even if Class is not covered by this talk, I recommand you to watch this video: https://www.youtube.com/watch?v=ya4UHuXNygM

I hope this helped :)

🌐
Medium
medium.com › programming-essentials › class-vs-factory-function-exploring-the-way-forward-73258b6a8d15
Class vs Factory function: exploring the way forward | by Cristian Salcescu | Frontend Essentials | Medium
April 29, 2021 - Learn more on JavaScript, functional programming, and front-end development. ... ECMAScript 2015 (aka ES6) comes with the class syntax, so now we have two competing patterns for creating objects. In order to compare them, I’ll create the same object definition (TodoModel) as a class, and then as a factory function.