I am trying to wrap my head around different Module pattern declinations. I see different ways of writing these modules and exposing their data.
I'm expecting information on advantages/disadvantages, better patterns not described here, use cases for each of them.
A) Object literal wrapped in a self invoking function, firing off with an init method: (source)
(function() {
var MyModule = {
settings: {
someProperty: 'value';
}
init: function() {
someMethod();
}
someMethod: function() {
// ...
}
};
MyModule.init();
})();
This is an example of a simple "Tweet This" utility I built. Am I using this pattern correctly? So far it's the only one that I have actual experience in writing.
B) Module as a namespaced self-invoking anonymous function: (source)
var MyModule = (function () {
var MyObj = {}
function privateMethod() {
// ...
}
MyObj.someProperty = 1;
MyObj.moduleMethod = function () {
// ...
};
return MyObj;
}());
Are there any advantages/disadvantages over the previous style? Also, what would be the implications of using object literal notation here instead of the dot syntax in the example? Object literal seems cleaner and easier, but I'm not really aware of the proper use cases for each?
C) Module as a namespaced self-invoking anonymous function, but only exposing desired results through a return block: (source)
var MyModule = (function() {
var myPrivateVar, myPrivateMethod;
myPrivateVar = 0;
myPrivateMethod = function(foo) {
console.log(foo);
};
return {
myPublicVar: "foo",
myPublicFunction: function(bar) {
myPrivateVar++;
myPrivateMethod(bar);
}
};
})();
Similar to the previous style, but instead of exposing an entire object with all of it's properties/methods, we're just exposing specific bits of data through a return statement.
D) Module as a function wrapped in a self-invoking anonymous function, with nested functions acting as methods. The module is exposed through the window object, then constructed via the new keyword: (source)
(function(window, undefined) {
function MyModule() {
this.myMethod = function myMethod() {
// ...
};
this.myOtherMethod = function myOtherMethod() {
// ...
};
}
window.MyModule = MyModule;
})(window);
var myModule = new MyModule();
myModule.myMethod();
myModule.myOtherMethod();
I'm assuming the strength of this pattern is if the module is a 'template' of sorts where multiple entities may need to exist within an application. Any specific examples of a good use case for this?
All of these are using the same pattern just in slightly different ways.
A) Object literal wrapped in a self invoking function, firing off with an init method:
This is fine if you don't intend to allow anyone else to access a chunk of code. You don't even have to have an init function. Wrapping your code in an IIFE (immediately invoked function expression) prevents global namespace pollution and allows the use of "private" variables. In my opinion, this is just good practice, not a module.
B) Module as a namespaced self-invoking anonymous function:
This is what people mean when they're talking about the module pattern. It gives you private variables and functions then exposes those through a public interface. That interface just so happens to be called MyObj in your example.
C) Module as a namespaced self-invoking anonymous function, but only exposing desired results through a return block:
This is actually exactly the same thing a B. The only difference is that methods on the interface can't directly reference the interface itself like you can in B. Example:
MyObj.methodA = function() {
return MyObj.methodB();
};
That will work with the previous example because you have a name to reference it but is only useful when you expect public methods to be called using anything other than the returned object as the execution context. i.e, setTimeout(MyModule.methodA) (that will be called with the global context so this.methodB() would not work as intended.
D) Module as a function wrapped in a self-invoking anonymous function, with nested functions acting as methods. The module is exposed through the window object, then constructed via the new keyword:
Same thing as the previous 2 except for 2 minor differences. window is passed as an argument because it has historically been true that it's faster to access a local variable than a global variable because the engine doesn't have to climb up the scope chain. However, most JS engines these days optimize accessing window since it's common and a known object. Likewise, undefined is given as a parameter with nothing passed as an argument. This ensures you have a correct undefined value. The reasoning behind this is that technically, you can assign any value to undefined in non-strict mode. Meaning some 3rd party could write undefined = true; and suddenly all of your undefined checks are failing.
The other difference is that you're returning a function instead of an object. The bonus behind this is that you can have private variables which are shared in each instance of an object, as well as private variables per instance. Example:
var count = 0;
function MyObject(id) {
var myID = id;
count++;
// Private ID
this.getID = function() {
return myID;
};
// Number of instances that have been created
this.getCount = function() {
return count;
};
}
The downside to this is that you aren't attaching methods to the prototype. This means that the JS engine has to create a brand new function for every single instance of the object. If it was on the prototype, all instances would share the same functions but could not have individual private variables.
Related
I am new to Javascript and am still getting my head round the various ways of creating objects i.e constructor+new, prototypal, functional & parts.
I have created what I think is an object factory using the module pattern and want to know what the correct method of calling an internal method would be. Is it via this or function name.
Here is my module:
function chart() {
function my() {
// generate chart here, using `width` and `height`
}
my.sayHi = function(){
console.log('hi');
my.sayBye();
};
my.sayBye = function(){
console.log('Bye');
};
return my;
}
var test = chart();
test.sayHi();
You can see that the first function calls the second using my.sayBye() or is it better to use this.sayBye(). Both produce the same result and run without error.
The module pattern allows you to dispense with the 'this' variable if you want to. I would probably rewrite the above code to look like this and then the question becomes moot.
function chart() {
var hiCount = 0;
function sayHi(){
console.log('hi');
hiCount++;
sayBye();
};
function sayBye(){
console.log('Bye');
};
return {
sayHi : sayHi,
sayBye: sayBye
};
}
var test = chart();
test.sayHi();
In the above code all is defined within the function chart. As JavaScript's scope is at the function level every time the chart function is called a new set of functions will be defined. And a new set of variables can also be defined that are private to the function as they are defined in the function and are not accessible from outside. I added hiCount as an example of how you could do this. The Module pattern allows privacy in JavaScript. It eats more memory than the prototype pattern though as each time a function is declared it is not shared between other instances of the same class. That is the price you have to pay in Javascript to have class variables that are private. I willingly pay it. Removing 'this' from my code makes it easier to understand and less likely that I will fall into problems of misplaced scope.
Using "this" is better approach because you would be able to bind the function directly to the parent function object.And you dont need to return anything from the function.
where as in your case you are explicitly returning another function
Here is the use of "this" approach
function chart() {
this.sayHi = function(){
console.log('hi');
}
}
var test = new chart();
test.sayHi();
Using this approach you would be able to call anything in the prototype of function "chart"
Eg
chart.prototype.hello = function(){
console.log('hello')
}
So you would be able to call the hello function from the same object(test)
In JavaScript, classes are usually emulated through constructors. However, I'm curious as to how one can create an encapsulated class, i.e. a class that keeps some of it's members private.
The commonly seen way of creating a 'class' is as follows:
function MyClass(parameter) {
this.value = parameter;
}
MyClass.prototype.myPublicFunction = function() {
console.log("About to run private function.");
myPrivateFunction();
};
MyClass.prototype.myPrivateFunction = function() {
...
};
As you can see, in this example myPrivateFunction is actually public. One approach I've seen to solve this problem is the following:
function MyClass(parameter) {
this.value = parameter;
this.myPublicFunction = function() {
console.log("About to run private function.");
myPrivateFunction.call(this);
}
function myPrivateFunction() {
...
}
}
This works; myPrivateFunction is inaccessible from the outside. But this approach has a problem - all functions in this 'class' are going to be copied across instances, instead of shared through the prototype. Also using privateFunction.call(this) everywhere isn't awesome.
Same goes for non-function members. How can I define a private instance-member in a class? What is the best and what is the most common approach? Is it acceptable to simply rely on a naming convention (such as beginning private function names with a _)?
You could create a scope to hide you private functions with an auto executing function.
Like:
(function(){
function myPrivateFunction(arg_a, arg_b) {
/* ... */
console.log("From priv. function " + this.value);
}
window.MyClass = function(parameter) {
this.value = parameter;
this.myPublicFunction = function() {
console.log("About to run private function.");
myPrivateFunction.call(this, 'arg_a', 'arg_b');
}
}
})();
But then you need to use MyClass only after it is declared since now it is an function expression and not a function statement, but all instances of MyClass will share the same instance of myPrivateFunction. but you will need to use Function.prototype.call (as in myPrivateFunction.call(this, 'arg_a', 'arg_b'); to get the value of this keyword to match your instance.
If you do just myPrivateFunction('arg_a, 'arg_b'); the keyword this will point to the global object (window on browsers) or null if 'strict mode' is enabled.
Just a note: In my own code I don't do this but rely on naming conventions like MyClass.prototype._myPrivateFunction = function(){}; when not using some framework.
I have come to understand that constructor functions can be instantiated to create new objects in javascript which has its own _proto_ property and also giving the property 'prototype' to the constructor function.
function MyController() {
var controllerName = 'initialcontroller';
function init() {
console.log(controllerName);
}
this.init = init;
}
Here, init can be called like this:
var mycontroller = new MyController();
mycontroller.init();
Supposing I am only instantiating only once and never again, isn't this an overkill if I don't intend to use all the prototype properties being provided by the MyController.prototype ?
Question: Instead, can i not code like this using the revealing module pattern?
var myController = function() {
var controllerName = 'initialcontroller';
function init() {
console.log(controllerName);
}
return {
init : init
}
}();
Here, init can be called like this:
myController.init();
In this case, if I try to access any property inside myController that is not present, the javascript engine won't try to find whether the property exists anywhere in the prototype chain, thus saving my time.
Or is there any other advantages of instantiating a function that i am overlooking?
If you simply want a "singleton"-like object with some methods and other properties, you could just use an object literal to simplify things even more:
var myController = {
init: function (foo) {
// do something with foo or whatever
}
}
myController.init("bar");
Or - if you need some "private" internal state, use the regular revealing module pattern:
var myController = (function () {
var internal = "i am private";
return {
init: function () {
// blah blah
}
};
}());
myController.init();
About the prototype lookup time: Yeah, theoretically, the lookup traverses up the prototype chain when you're trying to access a non-existing property. Theoretically, this might be a tiny bit faster for plain ol' Object instances that have "no" specific constructor. In reality, this performance impact should be quite negligible. Don't attempt to optimize here unless you REALLY need it. :)
Conside the following JavaScript code. The function definitions all seem to achieve the same thing. Is there any recommended convention for defining the functions which are then 'revealed' in the return dictionary object?
var testModule = (function(){
var counter = 0;
var localFunc1 = function() {
return "local 1";
}
function localFunc2() {
return "local 2";
}
this.localFunc3 = function() {
return "local 3";
}
localFunc4 = function() {
return "local 4";
}
return {
proxy1: localFunc1,
proxy2: localFunc2,
proxy3: localFunc3,
proxy4: localFunc4
};
})();
I don't think that there is any real preferred method. The most common setup I've seen involves creating all of your methods as local (using var) then returning an object that exposes the public methods.
A couple of things to note:
this.localFunc3 will only work if your object is instantiated with the 'new' keyword
when returning your object, remove the () from each function so that you are returning a reference to the function and not the function's returned value
localFunc4 will be global since it has no 'var' keyword in front of it
When working with a module pattern like this, I tend to go for something along the lines of:
var Obj = ( function () {
var private_static = 'this value is static';
return function () {
//-- create return object
var _self = {};
//-- create private variables
var private_variable = 'this value is private';
var func1 = function () {
return 'value 1';
};
//-- attach public methods
_self.func1 = func1;
//-- return the object
return _self;
};
} )();
Some notes about this method:
allows for private static variables (if you don't need private static variables, you can remove the closure)
by creating the _self reference first, you can pass a self reference to any objects instantiated from within that need a reference to their parent
I like that I can reference all internal functions without _self.whatever or this.whatever, ignoring whether or not they are private or public
The definitions do not achieve the exact same thing.
var localFunc1 and function localFunc2 do the same thing, they create functions only available inside your outer function.
this.localFunc3 and localFunc4 are not really local functions: they both belong to the window object (this in that context is window, and localFunc4 is declared without the var statement).
So, the latter two don't even need to be exposed on your returned object, since they're already global. And, actually, you are not exposing any functions on your return object, you are exposing their return values, since you invoke each of them. Were you trying to do this?
return {
proxy1: localFunc1,
proxy2: localFunc2,
proxy3: localFunc3,
proxy4: localFunc4
};
Note: I recommend you watch this video where Douglas Crockford explains the multiple ways to deal with inheritance in JavaScript. I believe you are looking for what he calls "parasitic inheritance".
I'm a bit confused, how can I create public and private members.
My code template so far is like:
(function()){
var _blah = 1;
someFunction = function() {
alert(_blah);
};
someOtherFunction = function() {
someFunction();
}
}();
You may want to use the Yahoo Module Pattern:
myModule = function () {
//"private" variables:
var myPrivateVar = "I can be accessed only from within myModule."
//"private" method:
var myPrivateMethod = function () {
console.log("I can be accessed only from within myModule");
}
return {
myPublicProperty: "I'm accessible as myModule.myPublicProperty."
myPublicMethod: function () {
console.log("I'm accessible as myModule.myPublicMethod.");
//Within myProject, I can access "private" vars and methods:
console.log(myPrivateVar);
console.log(myPrivateMethod());
}
};
}();
You define your private members where myPrivateVar and myPrivateMethod are defined, and your public members where myPublicProperty and myPublicMethod are defined.
You can simply access the public methods and properties as follows:
myModule.myPublicMethod(); // Works
myModule.myPublicProperty; // Works
myModule.myPrivateMethod(); // Doesn't work - private
myModule.myPrivateVar; // Doesn't work - private
You don't. You can rely on convention, prepending _ to your private attributes, and then not touching them with code that shouldn't be using it.
Or you can use the function scope to create variables that can't be accessed from outside.
In javascript every object member is public. Most popular way of declaring the private field is to use the underscore sign in it's name, just to make other people aware that this is private field:
a = {}
a._privateStuff = "foo"
The other way to hide the variable is using the scopes in javascript:
function MyFoo {
var privateVar = 123;
this.getPrivateVar = function() {
return privateVar;
}
}
var foo = new MyFoo();
foo.privateVar // Not available!
foo.getPrivateVar() // Returns the value
Here's the article that explains this technique in details:
http://javascript.crockford.com/private.html
Three things:
IIFEs:
It seems like you need to refresh your knowledge regarding this pattern. Have a look at this post before using an IIFE again.
Global public vs. Safe public:
Skipping var keyword with someFunction and someOtherFunction leads to registration of these function objects in the global scope, i.e., these functions can be called and reassigned from anywhere in the code. That could lead to some serious bugs as the code grows bigger in size. Instead, as Daniel suggested, use the module pattern. Though you can use other methods too like Constructors, Object.create(), etc, but this is pretty straightforward to implement.
/* create a module which returns an object containing methods to expose. */
var someModule = (function() {
var _blah = 1;
return {
someFunction: function() {},
someOtherFunction: function() {}
};
})();
/* access someFunction through someModule */
someModule.someFunction();
// ...
// ....
/* after 500+ lines in this IIFE */
/* what if this happens */
someFunction = function() {
console.log("Global variables rock.");
};
/* Fortunately, this does not interfere with someModule.someFunction */
Convention and scope combined:
We cannot expect from every developer to follow the underscore or the capitalization convention. What if one of them forgets to implement this technique. Instead of just relying upon the convention (_private, GLOBAL) and the scope (function scoping), we can combine both of them. This helps in maintaining consistency in coding style and provides proper member security. So, if next time somebody forgets to capitalize their globals, the console (in strict mode) can prevent the world from ending.
Javascript doesn't have true private members. You have to abuse scope if your really need privacy.
I hope this URL will solve your problem...see that...
http://robertnyman.com/2008/10/14/javascript-how-to-get-private-privileged-public-and-static-members-properties-and-methods/