I am struggling with the concept of modules, factory functions, and constructors...
I am the most curious about the difference between module and factory function, and when to use what?
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
I think the explanation above is great for constructors. I'm new to javascript, but I just asked myself this question and did some reading on it. For the difference between factory functions and the module pattern I think it comes down to a little bit of syntax (which governs use). Hopefully, what I have below explains it correctly:
> const Factoryfunction = (parameters) => {
> const/let/var properties = values
> const methods = (parameters) => {
> //do stuff
> }
> return {public variables and methods}
}; <---- here's the big difference!
const modulePattern = ((parameters) => {
const/let/var properties = values
const methods = (parameters) => {
//do stuff
}
return {public properties and methods}
})(); <---- here's the big difference!
Module Pattern:
From my understanding, that little set of parenthesis at the end changes how the previous block of code works. With the parenthesis, you have access to whatever public methods or properties that you created. You can also create private methods and properties with in the module to tighten control on how the module is used/ do more intricate and organized work. Those public properties/methods can be used in a variety of contexts. You can also update the properties within a module through the methods defined ore externally if that property is return (public). Now you can call these methods using the module's declared name:
modulePattern.publicMethod();
console.log(publicProperty)
Factory functions:
Without () at the end, you have a factory function that can be used to create new objects without the "new" keyword that is used with constructors:
const object = factoryFunction (parameters)
console.log(object.property)// logs property defined in factory function but based on new parameters
object.method()// calls the method defined in factory function which is now adjusted to new parameters (if that's how they work)
both factory functions and the module pattern have the following benefits:
Organizing code, improving readability and logical flow, de-cluttering the window's namespace (google scope and closure) and my favorite, being able to define whether a property or method is private or public (which benefits the security and debug-ability and more of your code). Also, reduce reuse and recycle.
This is my first contribution on Stack! I hope it's helpful!
here's where I learned all of that: https://www.theodinproject.com/lessons/node-path-javascript-factory-functions-and-the-module-pattern
Related
Can someone clarify the difference between a constructor function and a factory function in Javascript.
When to use one instead of the other?
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.
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).
A constructor returns an instance of the class you call it on. A factory function can return anything. You would use a factory function when you need to return arbitrary values or when a class has a large setup process.
A Constructor function example
function User(name) {
this.name = name;
this.isAdmin = false;
}
let user = new User("Jack");
new creates an object prototyped on User.prototype and calls User with the created object as its this value.
new treats an argument expression for its operand as optional:
let user = new User;
would cause new to call User with no arguments.
new returns the object it created, unless the constructor returns an object value, which is returned instead. This is an edge case which for the most part can be ignored.
Pros and Cons
Objects created by constructor functions inherit properties from the constructor's prototype property, and return true using the instanceOf operator on the constructor function.
The above behaviors can fail if you dynamically change the value of the constructor's prototype property after having already used the constructor. Doing so is rare, and it can't be changed if the constructor were created using the class keyword.
Constructor functions can be extended using the extends keyword.
Constructor functions can't return null as an error value. Since it's not an object data type, it is ignored by new.
A Factory function example
function User(name, age) {
return {
name,
age,
}
};
let user = User("Tom", 23);
Here the factory function is called without new. The function is entirely responsible for the direct or indirect use if its arguments and the type of object it returns. In this example it returns a simple [Object object] with some properties set from arguments.
Pros and Cons
Easily hides the implementation complexities of object creation from the caller. This is particularly useful for native code functions in a browser.
The factory function need not always return objects of the same type, and could even return null as an error indicator.
In simple cases, factory functions can be simple in structure and meaning.
Objects returned do not generally inherit from the factory function's prototype property, and return false from instanceOf factoryFunction.
The factory function can't be safely extended using the extends keyword because extended objects would inherit from the factory functions prototype property instead of from the prototype property of the constructor used by the factory function.
Factories are "always" better. When using object orientated languages then
decide on the contract (the methods and what they will do)
Create interfaces that expose those methods (in javascript you don't have interfaces so you need to come up with some way of checking the implementation)
Create a factory that returns an implementation of each interface required.
The implementations (the actual objects created with new) are not exposed to the factory user/consumer. This means that the factory developer can expand and create new implementations as long as he/she doesn't break the contract...and it allows for the factory consumer to just benefit from the new API without having to change their code...if they used new and a "new" implementation comes along then they have to go and change every line which uses "new" to use the "new" implementation...with the factory their code doesn't change...
Factories - better than all anything else - the spring framework is completely built around this idea.
Factories are a layer of abstraction, and like all abstractions they have a.cost in complexity. When encountering a factory based API figuring out what the factory is for a given API can be challenging for the API consumer. With constructors discoverability is trivial.
When deciding between ctors and factories you need to decide if the complexity is justified by the benefit.
Worth noting that Javascript constructors can be arbitrary factories by returning something other than this or undefined. So in js you can get the best of both worlds - discoverable API and object pooling/caching.
I think the factory function is superior to the constructor function. Using new with the constructor function, we are binding our code to one specific way of creating an object, while with a factory, we are free so we can create more different instances without binding ourselves. Let's say we have this class:
const file = new CreateFile(name)
If we want to refactor CreateFile class, creating subclasses for the file format our server supports, we can write an elegan factory function:
function CreateFile(name) {
if (name.match(/\.pdf$/)) {
return new FilePdf(name);
} else if (name.match(/\.txt$/)) {
return new FileTxt(name);
} else if (name.match(/\.md$/)) {
return new FileMd(name);
} else {
throw new Error("Not supprted file type");
}
}
with factory functions, we can implement private variables, hide the information from the users which is called encapsulation.
function createPerson(name) {
const privateInfo = {};
// we create person object
const person = {
setName(name) {
if (!name) {
throw new Error("A person must have a name");
}
privateInfo.name = name;
},
getName() {
return privateInfo.name;
},
};
person.setName(name);
return person;
}
For the differences, Eric Elliott clarified very well,
But for the second question:
When to use one instead of the other?
If you are coming from the object-oriented background, Constructor function looks more natural to you.
this way you shouldn't forget to use new keyword.
This question already has answers here:
var functionName = function() {} vs function functionName() {}
(41 answers)
Closed 5 years ago.
With a js module pattern, I think functions are commonly defined like this:
var loadData = function(myParam1, myParam2){}
However, the js module pattern still works with functions defined like this:
function loadData (myParam1, myParam2){}
Is there any practical reason to define functions as variables in a js module? Is a function variable generally expected from a design standards perspective for a publicly exposed method within a js module? Or is the implementation style really more of a matter of personal preference?
Module pattern is usually augmented by IIFE pattern:
(function(){
})();
Here is an example:
var MODULE = (function(){
function anotherLoadData(myParam1, myParam2){
console.log('another load data')
}
return {
loadData : function(myParam1, myParam2){
console.log('load data');
},
anotherLoadData : anotherLoadData
}
})();
MODULE.loadData();
MODULE.anotherLoadData();
So you see, the way you declared your functions doesn't relate to js module pattern.
Will this edited answer will be better:
[Learning JavaScript Design Patterns][1]
The Module Pattern
The Module pattern was originally defined as a way to provide both private and public encapsulation for classes in conventional software engineering.
In JavaScript, the Module pattern is used to further emulate the concept of classes in such a way that we're able to include both public/private methods and variables inside a single object, thus shielding particular parts from the global scope. What this results in is a reduction in the likelihood of our function names conflicting with other functions defined in additional scripts on the page.
The Module pattern encapsulates "privacy", state and organization using closures. It provides a way of wrapping a mix of public and private methods and variables, protecting pieces from leaking into the global scope and accidentally colliding with another developer's interface. With this pattern, only a public API is returned, keeping everything else within the closure private.
This gives us a clean solution for shielding logic doing the heavy lifting whilst only exposing an interface we wish other parts of our application to use. The pattern is quite similar to an immediately-invoked functional expression (IIFE - see the section on namespacing patterns for more on this) except that an object is returned rather than a function.
It should be noted that there isn't really an explicitly true sense of "privacy" inside JavaScript because unlike some traditional languages, it doesn't have access modifiers. Variables can't technically be declared as being public nor private and so we use function scope to simulate this concept. Within the Module pattern, variables or methods declared are only available inside the module itself thanks to closure. Variables or methods defined within the returning object however are available to everyone.
History
From a historical perspective, the Module pattern was originally developed by a number of people including Richard Cornford in 2003. It was later popularized by Douglas Crockford in his lectures. Another piece of trivia is that if you've ever played with Yahoo's YUI library, some of its features may appear quite familiar and the reason for this is that the Module pattern was a strong influence for YUI when creating their components.
Examples
Let's begin looking at an implementation of the Module pattern by creating a module which is self-contained.
var testModule = (function () {
var counter = 0;
return {
incrementCounter: function () {
return counter++;
},
resetCounter: function () {
console.log( "counter value prior to reset: " + counter );
counter = 0;
}
};
})();
// Usage:
// Increment our counter
testModule.incrementCounter();
I've been using this pattern in my JS code:
function Thing() {
var otherData = {
// Private variables?
name : "something"
}
var myThing = {
data: "somedata",
someFunction: function () {
console.log(otherData.name);
}
}
return myThing;
}
Then when using it doing:
var thing = Thing();
thing.someFunction();
I've seen examples of constructors and singletons in JS, but I haven't run across this pattern before. Is there a name for this pattern? Are there any potential problems with this pattern? Previously I was just using the object literal pattern, but wanted to get private-ish variables by putting it in a closure.
Is there a name for this pattern?
That has various names. The common ones I've heard for it are:
factory function
maker function (this is the term Douglas Crockford, who popularized them, uses)
builder function
To avoid confusion we don't call them "constructor functions" or "constructors" as that term is specifically for functions used with new, which yours isn't.
(Note: "builder function" in this context is not related to the builder pattern [e.g., GoF patterns]. That's a completely different thing. Similarly, "factory function" here isn't really related to the factory pattern, but in this case there's overlap, as the factory pattern uses factory functions. "Maker" has the advantage of not having that potential confusion; I'm sure there's some "maker pattern" somewhere, but at least not in the initial GoF book.)
Are there any potential problems with this pattern?
Well, there are potential problems with all patterns. :-) There's nothing particularly problematic with this one, though, no.
Just to point out one problem it doesn't have: Someone might mention that you aren't leveraging prototypes with that pattern, but perhaps you just don't need one with that particular builder, and if you did, you could easily use one:
var thingProto = {
method: function() {
// I'm a shared method
}
};
function buildThing() {
var otherData = {
// Private variables?
name : "something"
}
var myThing = Object.create(thingProto);
myThing.data = "somedata";
myThing.someFunction = function () {
console.log(otherData.name);
};
return myThing;
}
Doesn't change the pattern.
As a style note, normally you wouldn't capitalize it, as the overwhelming convention in JavaScript is that a capitalized function is a constructor function. So Thing might be called createThing or buildThing or just thing.
The constructor invocation pattern is when you prefix a function call with the new keyword followed by a space. This allows the function to act as a constructor, assigning its prototype property (ConstructorFunction.prototype) as the prototype attribute (instanceObj.__proto__) of the returned object, and modifying the object's properties through the this keyword. Therefore, the way you're using that function is not a "constructor pattern".
The encapsulation of data using function closures is commonly referred to as the Module Pattern.
Here is the relevant section from Addy Osmani's book: Learning JavaScript Design Patterns.
The Module pattern was originally defined as a way to provide both
private and public encapsulation for classes in conventional software
engineering.
In JavaScript, the Module pattern is used to further emulate the
concept of classes in such a way that we're able to include both
public/private methods and variables inside a single object, thus
shielding particular parts from the global scope. What this results in
is a reduction in the likelihood of our function names conflicting
with other functions defined in additional scripts on the page.
Privacy
The Module pattern encapsulates "privacy", state and organization
using closures. It provides a way of wrapping a mix of public and
private methods and variables, protecting pieces from leaking into the
global scope and accidentally colliding with another developer's
interface. With this pattern, only a public API is returned, keeping
everything else within the closure private.
This gives us a clean solution for shielding logic doing the heavy
lifting whilst only exposing an interface we wish other parts of our
application to use. The pattern is quite similar to an
immediately-invoked functional expression (IIFE - see the section on
namespacing patterns for more on this) except that an object is
returned rather than a function.
It should be noted that there isn't really an explicitly true sense of
"privacy" inside JavaScript because unlike some traditional languages,
it doesn't have access modifiers. Variables can't technically be
declared as being public nor private and so we use function scope to
simulate this concept. Within the Module pattern, variables or methods
declared are only available inside the module itself thanks to
closure. Variables or methods defined within the returning object
however are available to everyone.
I often use the pattern of a main JavaScript constructor function and adding methods to its prototype object so they can be called intuitively by the user, for example:
function Slideshow(options) {
this.options = options
this.slideshow = $('#slideshow')
//more variables here
}
Slideshow.method1 = function () {
this.slideshow.addClass('test') // do something with slideshow variable
};
Slideshow.method2 = function () {
// another method
};
The one thing that really bugs me about this pattern is how in order to make variables accessible across all prototype methods, I have to add "this" in front of each variable inside the constructor function. It's a major pain, and I can't help but think there's a more elegant way to do this.
If I forgo using the prototype object and just add the methods as instance methods, I know I can't get around this problem, but I like the efficiency? and self encapsulating nature of this pattern. Any other suggestions for a better pattern? Thanks!
It's a major pain
No, it's really not. Every single JavaScript developer uses this syntax. If you were in Ruby or Python, you'd use self., in PHP you'd use $this->. Some languages like C++ don't require any special decorator, but JavaScript does.
and I can't help but think there's a more elegant way to do this.
No, there isn't.
This is JavaScript's syntax, you cannot change it, and you cannot work around it. If you want to access a property of this, you need this. before the property name. Otherwise, you're talking about global variables.
If you want a different syntax, consider a different language like CoffeeScript, which compiles to JavaScript.
meager has pretty much summed things up if you're talking about accessing public instance properties or methods. You have to use this in front of it as that's just how the language works.
But, if you have private instance properties or methods, you can define those as local variables inside the constructor and you can access them without this.
function slideshow(options) {
// no need to resave the options arguments as they can be used
// directly from the argument variable
// define a per-instance private variable that other methods defined
// within the constructor can use directly without the use of `this`
var theShow = $(options.selector || '#slideshow');
// define public methods
this.method1 = function() {
// can access private instance variable here without this in front of it
theShow.addClass('test');
}
this.method2 = function() {
theShow.addClass(options.decoaration);
}
}
This general design pattern is described here: http://javascript.crockford.com/private.html
Practically speaking, this works because the constructor function with the public methods declared inside it creates a closure that lasts for the duration of the object lifetime so the local variables in the constructor become per-instance variables accessible only from the functions declared within the constructor.
I have a few questions about using the Module Pattern for JavaScript programming. I have seen guides on the pattern that utilize it in 2 different ways. The first is like this:
This method is from CSS Tricks,
Module Pattern
var s,
NewsWidget = {
settings: {
numArticles: 5,
articleList: $("#article-list"),
moreButton: $("#more-button")
},
init: function() {
// kick things off
s = this.settings;
}
};
The second method, I will use the same code but in a different way.
var s,
NewsWidget = (function(){
// Any variables or functions in here are private
var privateVar;
// All variables or functions in returned object become public
return {
settings: {
numArticles: 5,
articleList: $("#article-list"),
moreButton: $("#more-button")
},
init: function() {
// kick things off
s = this.settings;
}
}
}());
Now looking at these two examples, my assumption would be to only use the latter method because of the ability to use private variables due to closures..? Am I correct? The first method does not use a closure and therefore is in the global memory scope and cannot have private members. Why is it then, that CSS Tricks and other people use the first method as an example when it does not seem to have any real purpose?
Secondly, I am curious how the Module Pattern handles multiple objects of the same type? Unlike the Factory Pattern which is used to get any number of JavaScript Objects, the Module Pattern just executes the anonymous function once, therefore if I have a Module called BlogPost that defines all the attributes of a blog post, then how can I create multiple instances of this object?
my assumption would be to only use the latter method because of the ability to use private variables due to closures..? Am I correct?
Yes. If you need private variables.
The first method does not use a closure and therefore is in the global memory scope and cannot have private members.
Notice however that even in the second example, the s variable is unnecessarily global.
Why is it then, that CSS Tricks and other people use the first method as an example when it does not seem to have any real purpose?
For simplicity. Either when you don't have local variables around (because you don't need them, or you did model private things as properties), or when the author just doesn't care. Or didn't bother to write down the implicit IEFE.
Secondly, I am curious how the Module Pattern handles multiple objects of the same type?
It does not. Modules are singletons. They can have constructors or factories as fields, though, when you need to instantiate module-related objects. Still, there is only ever one (global) module object.
Your first example is not a Module Pattern, its a simple Object Literal initializer.
Only the second example are a Module Pattern, first example doesn't give the possibility to define encapsulation of private member or function
Quoted from Learning JavaScript Design Patterns, this is the typical pattern(there is some variation):
In JavaScript, the Module pattern is used to further emulate the
concept of classes in such a way that we're able to include both
public/private methods and variables inside a single object, thus
shielding particular parts from the global scope. What this results in
is a reduction in the likelihood of our function names conflicting
with other functions defined in additional scripts on the page.
var myNamespace = (function () {
var myPrivateVar, myPrivateMethod;
// A private counter variable
myPrivateVar = 0;
// A private function which logs any arguments
myPrivateMethod = function( foo ) {
console.log( foo );
};
return {
// A public variable
myPublicVar: "foo",
// A public function utilizing privates
myPublicFunction: function( bar ) {
// Increment our private counter
myPrivateVar++;
// Call our private method using bar
myPrivateMethod( bar );
}
};
})();