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.
Related
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
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 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 been doing research to come up with a standardized Javascript coding style for my team. Most resources now recommend the "Module" pattern that involves closures, such as this:
var Module = function() {
someMethod = function() { /* ... */ };
return {
someMethod: someMethod
};
}();
and invoke it like Module.someMethod();. This approach seems to only work with methods that would be static in a traditional OOP context, for example repository classes to fetch/save data, service layers to make outside requests, and the like. Unless I missed something, the module pattern isn't intended to be used with data classes (think DTOs) that would typically need to be passed to/from the service methods to the UI glue code.
A common benefit I see cited is that you can have true private methods and fields in Javascript with the module pattern, but this can also be achieved along with being able to have static or instance methods with the "classical" Javascript style similar to this:
myClass = function(param) {
// this is completely public
this.publicProperty = 'Foo';
// this is completely private
var privateProp = param;
// this function can access the private fields
// AND can be called publicly; best of both?
this.someMethod = function() {
return privateProp;
};
// this function is private. FOR INTERNAL USE ONLY
function privateMethod() {
/* ... */
};
}
// this method is static and doesn't require an instance
myClass.staticMethod = function() { /* ... */ };
// this method requires an instance and is the "public API"
myClass.prototype.instanceMethod = function() { /* ... */ };
So I guess my question is what makes the Module Pattern better than the traditional style? It's a bit cleaner, but that seems to be the only benefit that is immediately apparent; in fact, the traditional style seems to offer the ability to provide real encapsulation (similar to true OOP languages like Java or C#) instead of simply returning a collection of static-only methods.
Is there something I'm missing?
Module Pattern can be used to create prototypes as well see:
var Module = function() {
function Module() {};
Module.prototype.whatever = function() {};
return Module
}();
var m = new Module();
m.whatever();
As the other poster said the clean global namespace is the reason for it. Another way to achieve this however is to use the AMD pattern, which also solves other issues like dependency management. It also wraps everything in a closure of sorts. Here's a great Introduction to AMD which stands for Asynchronous Module Definition.
I also recommend reading JavaScript Patterns as it thoroughly covers the reasons for various module patterns.
The module pattern above is pointless. All you are doing is using one closure to return a constructor with prototype. You could have achieved the same with:
function Module() {};
Module.prototype.whatever = function() {};
var m = new Module();
m.whatever();
In fact you would have saved one object (the closure) from being created, with the same output.
My other beef with the module pattern is it if you are using it for private encapsulation, you can only use it easily with singletons and not concrete classes. To create concrete classes with private data you end up wrapping two closers, which gets ugly. I also agree that being able to debug the underscore pseudo-private properties is a lot easier when they are visible. The whole notion of "what if someone uses your class incorrectly" is never justified. Make a clean public API, document it, and if people don't follow it correctly, then you have a poor programmer in your team. The amount of effort required in Javascript to hide variables (which can be discovered with eval in Firefox) is not worth the typical use of JS, even for medium to large projects. People don't snoop around your objects to learn them, they read your docs. If your docs are good (example using JSDoc) then they will stick to it, just like we use every 3rd party library we need. We don't "tamper" with jQuery or YUI, we just trust and use the public API without caring too much how or what it uses underneath.
Another benefit you forgot to mention to the module pattern, is that it promotes less clutter in the global namespace, ie, what people refer to when they say "don't pollute the global namespace". Sure you can do that in your classical approach, but it seems creating objects outside of anonymous functions would lend more easily to creating those objects in the global namespace.
In other words, the module pattern promotes self contained code. A module will typically push one object onto the global namespace, and all interaction with the module goes through this object. It's like a "main" method.
Less clutter in the global namespace is good, because it reduces the chances of collisions with other frameworks and javascript code.
http://a2.twimg.com/a/1302724321/javascripts/widgets/widget.js?1302801865
It is setup like this at a high level:
public namespace:
TWTR = window.TWTR || {};
Then a closure:
(function() {
...
})(); // #end application closure
Within the application closure:
TWTR.Widget = function(opts) {
this.init(opts);
};
(function() {
// Internal Namespace.
var twttr = {};
})();
Some methods are marked public, others private, and the only difference seems to be the naming convention (private starts with underscore '_').
Is it designed using the module pattern?
Why or what benefit do you get with a closure within a closure?
Since they load the widget.js before jquery, this means widget is designed to run w/o jquery since order matters correct?
Just trying to learn from this thing!
It is setup like this at a high level:
public namespace:
TWTR = window.TWTR || {};
That is bad coding practice, variables should always be declared with var. And there are no "namespaces" in javascript, that term is applied to the above construct but it isn't really appropriate. Better to say its methods are contained by an object.
Then a closure:
> (function() { ...
>
> })(); // #end application closure
That pattern has come to be called an immediately invoked function expression or iife. Not sure I like the name, but there you go. Anyway, it doesn't necessarily create any useful closures. A closure is only useful if a function creates variables that become bound to some other execution context that survives beyond the life of the function that created them (I hope that doesn't read like gobbledy-goop). You don't need an iife to create a closure.
However, you can use the above pattern to create closures since it's a function much like any other function.
Within the application closure:
> TWTR.Widget = function(opts) {
> this.init(opts); }; (function() {
> // Internal Namespace.
> var twttr = {}; })();
Some methods are marked public, others
private, and the only difference seems
to be the naming convention (private
starts with underscore '_').
The use of "public" and "private" are a bit misleading in javascript. The use of underscore to start identifer names indicates something that should only be used within the current scope, or by the "library" code itself. It's a bit redundant since the code should have a published API and any method that isn't part of the API shouldn't be avaialble externally.
But that is largely a matter of coding style and personal preference.
Is it designed using the module pattern?
Richard Cornford's "module pattern" is just that, a pattern. It's handy for simulating "private" variables in javascript, and also to share properties between functions or methods other than by the usual prototype inheritance. widget.js might be implemented (in parts) using the module pattern, but it it was likely designed by considering requirements and functionality. ;-)
Why or what benefit do you get with a closure within a closure?
Exactly the same benefits of any closure as stated above. Accessing variables essentially by placing them on an appropriate part of the scope chain is essentially the same as accessing properties via a [[prototype]] chain, only with (very different) mechanics - one uses identifier resolution on the scope chain, the other property resolution on the [[prototype]] chain.
Edit
One drawback is that the entire activation object that the closed variable belongs to is probably retained in memory, so if you just need access to a shared variable, better to consider some other scheme, perhaps even classic prototype inheritance. Or at least if you are going to use closures, try to keep the related activation object as small as reasonably possible (e.g. set any variables that aren't used to null just before exiting).
e.g.
var foo = (function() {
// Variables available for closure
var a, b, c;
// Use a, b, c for stuff
...
// Only want closure to c
a = null;
b = null;
return function() {
// use c
}
}());
Since they load the widget.js before jquery, this means widget is designed to run w/o jquery since order matters correct?
I can't access the linked resource right now (corporate blocking of twitter domain), but the load order suggests you are correct. However, some code execution might be delayed until the document is fully loaded so it isn't a guaranteee, you'll need to look at the code.