Pattern for global variables - javascript

I have a couple of variables in my application that I have to use in most of my closures, like variables holding preloaded requests, or variables holding the current state of application (that need to be changed dynamically in different places).
So my application structure looks like this:
(function() {
var MainModule = (function () {
})();
var Utils = (function () {
})();
var Events = (function () {
})();
})();
And I create these variable inside MainModule, but want to change them, remove them, etc, inside Utils and Events. I've been thinking about two ways:
Creating Context closure that keeps an array of those variables, and have get() and set() access methods.
Passing these variables to closures as arguments, but I coulnd't unset them and I'd have difficulties because of the way javascript passes arrays/objects to functions.
How should I handle it?

(function() {
var MainModule = (function () {
var mine;
return {
getMine: function(){ return mine; },
setMine: function(a){ mine = a; }
}
})();
var Utils = (function () {
return function(module){
module.getMine();
}
})();
var Events = (function () {
})();
})();
IIFE does not give anything to put into the MainModule variable so I'm assuming something else will be calling something within Utils. get/set is the safest way to give access to private variables. Like the comments said, IIFE should only be used when needed, otherwise it's just pointless abstraction.

Related

How to correctly reference an method set on an object when declaring a method on this object in Javascript?

Kind of basic I guess. I'm writing on a modular application and am often running into having to do something like this:
var foo = {};
foo.do_something = function () {
//...
};
foo.do_something_else = function () {
// ...
};
foo.do_all = function () {
var x = foo.do_something();
// ...
};
I prefer to stick with functional programming like this.
Question:
Is it safe to reference methods declared on foo inside the declaration of other methods? Any better idea on how to do this?
Thanks!
That is fine.
You can also use this keyword, that refers to the specific instance. Be careful with this, because during execution the scope can change (because for example you invoke a method of an other object...).
To avoid it a good practice is to set in the first row of the method the assignment var self=this and then you can always use self for referencing the object instance.
You could use the module approach to accomplish the same separation of functionality, but without having to worry about constantly referencing a global name.
var foo = (function() {
var do_something = function () {
//...
};
var do_something_else = function () {
// ...
};
var do_all = function () {
// Note: can refer to `do_something` directly.
var x = do_something();
// ...
};
return {
do_something: do_something,
do_something_else: do_something_else,
do_all: do_all
};
})();
In general, you can use an IIFE (immediately-invoked function expression) to create a local, private scope in which you can define whatever you need to without having to worry about polluting global scope, and export functions or objects from within as needed.

How to declare a function: as a separate function or in the same function

Hello Stackoverflow people,
The questions, is about code style and code maintainability, rather than search for some errors.
Let's assume that I am creating some module for node.js. This module, is exporting only one object, let's call this object "FileParser". During file parsing, there can be different preprocessing functions. They are very unique, and I am not planning to reuse them in other parts of the application.
Since, this module is exporting only one function - my question is next:
In case I have some utility functions for this module, should I define this functions in the function which is exported, or they should be defined outside this function.
Basically- this:
var FileParser = function(){
}
FileParser.prototype.methodToExport = function(){
var utilityFunction = function(){
//do some work, maybe even return values
}
//do some other work.
utilityFunction();
//do more other work
}
module.exports.FileParser = FileParser;
or this:
var FileParser = function(){
}
FileParser.prototype.methodToExport = function(){
//do some work before calling function
utilityFunction();
//do more and more work after calling function
}
function utilityFunction(){
//body of function goes here, maybe even returning some value
}
module.exports.FileParser = FileParser;
What is more readable, especially if there are few utility functions.
Thanks,
-D
If utilityFunction is not used as a closure (i.e. it does not access variables declared in the methodToExport function), there is no good reason to declare it inside that other function.
Put it outside, it makes the methodToExport shorter (and therefore more readable).
Since it resides in your "local" module scope, you don't even need to bother about global namespace pollution. If the number of utility functions grows, you might consider grouping them appropriately, e.g. by using the revealing module pattern.
In the first case, your function will be declared each time methodToExport is called, in the second you will have global function. Maybe you can use some kind of closure:
FileParser.prototype.methodToExport = function() {
function utilityFunction () {
//do some work, maybe even return values
}
return function () { // This is the real function, the one which will be export!
//do some other work
utilityFunction () ;
//do more other work
} ;
} () ;
Maybe there is a better way, but I would have done things like that!
JavaScript is flexible enough to permit such thing, the declaration bellow, works but is not a good pratice in my point of view.
var FileParser = function(){
}
FileParser.prototype.methodToExport = function(){
var utilityFunction = function(){
//do some work
}
utilityFunction();
}
module.exports.FileParser = FileParser;
You're declaring and call inside a function, but is more clearly to do this inside the declaration of your FileParser object.
So, you have good pattern of declaration the Revealing Pattern, proposed by Addy Osmani.
var FileParser = function(){
var utilityOne = function(){
}
this.methodToExport = function(){
// do some work
utilityOne();
}
}
module.exports.FileParser = FileParser;
This able you to hide some utility function as a kind of encapsulation, and show only the important functions outside.
You didn't ask about this, but I would recommend that you place your code inside an IIFE so there's one less variable in the top level closure, like this:
module.exports.FileParser = (function(){
var FileParser = function(){};
// Do your stuff
return FileParser;
})();
This saves your having to create a global variable for FileParser.
Now as for the question which you did ask -- should the utility function be defined within the exported function or outside of it -- my answer depends on whether you're only exporting a single function, or multiple. In your case, since you're only exporting a single function, my answer is that as long as you have a choice, I prefer the utility function defined outside because its closure scope is smaller that way. By "as long as you have a choice", I mean that your utility function isn't using anything defined within methodToExport.
module.exports.FileParser = (function(){
var FileParser = function(){};
var utilityOne = function(){};
FileParser.prototype.methodToExport = function(){
// do some work
utilityOne();
}
return FileParser;
})();
A smaller closure scope doesn't make much of a difference in most circumstances, but the following is an example where it does.
module.exports.FileParser = (function(){
var FileParser = function(){};
FileParser.prototype.methodToExport = function(){
var longArray = [ /* ... */ ];
var utilityOne = function(){
setInterval(function(){
console.log("Hello");
},1000);
};
utilityOne();
}
return FileParser;
})();
In the above example, longArray is in the closure of utilityOne() even though it isn't needed. The setTimeout's reference to longArray prevents it from being garbage collected.
module.exports.FileParser = (function(){
var FileParser = function(){};
var utilityOne = function(){
setInterval(function(){
console.log("Hello");
},1000);
};
FileParser.prototype.methodToExport = function(){
var longArray = [ /* ... */ ];
utilityOne();
}
return FileParser;
})();
Moving the utilityOne() definition out of the method definition shrinks its closure scope and allows the longArray to be garbage collected.

Access to external literal class inside a function

What I have is something like that:
jQuery(function($) {
'use strict';
var App = {
init: function() {
App.startTool();
}
[...]
and when I try to call App.init(); from another file it say that App is not defined.
I'm trying to create some test with jasmine and I've the same error.
How can I go inside this "literal class", nested inside a simple function, from external files?
Javascript has function scope. This means that variables defined within a function are only visible within that function. To access this variable from outside the function, you'll need to either declare it outside the function, attach it to the window or some other global object directly, or return it as a value from the function.
Declaring outside:
var App;
jQuery(function($) {
'use strict';
App = {
init: function() {
App.startTool();
}
[...]
Attaching to the window or other global namespace:
jQuery(function($) {
'use strict';
window.App = { //or namespace.App where namespace can be another global variable.
init: function() {
App.startTool();
}
[...]
The way you're wrapping it you're not going to be able to return the value, but if it was a different function you could do this:
var App= (function() {
'use strict';
var App = {
init: function() {
App.startTool();
}
return App;
}())
A little more on function scope: Variables declared within a function cannot be seen from outside that function. Variables declared outside a function can be seen from inside a function. So if you want an object to be global, you need to declare it outside any function, or set it as a property on something that already has been declared outside the function. In a browser, the window object is global by default. Other environments like nodejs or rhino will have their own global objects.
Its important to understand how JS scope works because its the foundation behind a lot of the more powerful features of the language, particularly closures and the module pattern.
Some people have also mentioned the benefits of namespacing. This is a good point for this context. Having a single global variable for a library or application allows you to avoid conflicts with other libraries or scripts you might be using. You can then attach your other variables to that global namespace variable and reference them as properties of that object. So instead of calling App.init directly, call myProgram.App.init() for instance.
If it is not exposed as a global than you can not touch it.
You would have to put it into some namespace that is in the global scope.
jQuery(function($) {
'use strict';
var App = {
init: function() {
App.startTool();
}
}
if (!window.myNamespace) {
window.myNamespace = {};
}
myNamespace.App = App;
});
The fun thing here is it will not exist until document.ready, not sure why you would want it wrapped with ready. The init call should be called on ready. So you are doing to have race conditions on what widget registers first.
You need to make App globally available if you want to use it from outside the function:
jQuery(function($) {
'use strict';
// attach it to window instead of using var
window.App = {
init: function() {
App.startTool();
}
};
});

Global variables in Javascript (jQuery)

So this is the first time I am using Javascript in a much more powerful context, having a thick client and doing much of the heavy-lifting through javascript in itself. I am using jQuery, and a lot of the code is getting muddy at the moment coz it's all just a bunch of functions.
Turns out for some of my functions, I required variables to be passed through multiple functions with their value being maintained. The obvious way of doing this is by declaring them outside of the scope of the function and then have the function manipulate it the way it ought to . (These variables are objects and not primitive type, so I guess javascript being pass by reference, this works).
For instance, I probably have something like this
var node = //init with some value;
$(document).ready(setup);
function setup()
{
A();
B();
}
function A()
{
// operate on var node
}
function B()
{
// operate on var node
}
This is obviously a scaled down version of my code, but captures the way I deal with global variables. My question is, is there a more elegant way to do the above ?
Thanks
Any reason why you can't do:
$(document).ready(function() {
var node = //init with some value;
setup(node);
function setup(node) {
A(node);
B(node);
}
function A(node) {
// operate on var node
}
function B(node) {
// operate on var node
}
});
In general, using global variables and functions is a bad idea and should be avoided wherever possible.
Note that while you appear to have been asking specifically about node, your functions setup, A and B are also all global variables in your version.
The simplest approach would be to put all these declarations inside an anonymous function:
$(document).ready(function() {
var node = ...;
function A() {
...
}
function B() {
...
}
function setup() {
A();
B();
}
setup();
});
Only use one global variable (or as few as possible). Make any functions or objects members of your one global variable.
Douglas Crockford says
An objective measure of the quality of a JavaScript program is How
many global variables and global functions does it have? A large
number is bad because the chance of bad interactions with other
programs goes up. Ideally, an application, library, component, or
widget defines only a single global variable. That variable should be
an object which contains and is the root namespace for all of your
stuff.
Yahoo’s single global is YAHOO. It is spelled in all caps to identify
it as something special, since all lower case is ordinary and initial
caps indicates a constructor. Being in all caps, it is unlikely that
someone would use it accidentally, which further reduces the
likelihood of collision.
http://www.yuiblog.com/blog/2006/06/01/global-domination/
Also, you can create objects to further organize your code.
GLOBAL.myObject = {};
GLOBAL.myObject.myFunction = ...
I prefer the "revealing module" pattern:
var myApp = (function () {
// privates
var node;
var a = function () {
// operate on node
};
var b = function () {
// operate on node
};
// publics
var init = function () {
// initialization stuff
a();
b();
};
return {
init: init
};
})();
$(document).ready(function () {
myApp.init();
});
This way you only ever have one global, myApp, which stores everything else your app needs.
I think it makes the code harder to understand, I'd much rather take the variable in as an argument and have it as a return.
$(function(){
var outcome = multiply(add(5));
});
function add(num)
{
return num+1;
}
function multiply(num)
{
return num*5;
}
If you feel like you absolutely want to have global variables wrap your stuff in a closure so it doesn't actually go to a global scope.
ie,
(function(){
var a; // can be used in any functions within this closure, but not polluting window
function A()
{
a = 'blah';
}
})();
There are many. For instance, objects.
// jQuery shorthand for "wait till DOM ready"
$( function() {
// create node object
var node = {
id: /* some value */,
setup: function() {
this.A();
this.B();
},
A: function() {
// operate on this.id
},
B: function() {
// operate on this.id
}
};
// setup node object
node.setup();
} );
Global variables are trouble waiting to happen. Don't dirty up your global namespace. Javascript is an object oriented language, use objects. Notice your object can have a property that you can reference with the this keyword from within the objects methods.

How can I safely access other sibling functions and variables in a Javascript Module Pattern without accessing something in the containing scope?

I have a Javascript Object structured after the Module Pattern. I have several private function in it which are called from other sibling "private" functions. How can I access another variable/function without the potential to accidentally access a global/external variable/object/function?
function doSomething() {
alert("Something I don't want to do");
}
var My.Namespaced.SingletonClass = (function() {
var init = function() {
doSomething();
}
var doSomething = function() {
alert("Something I want to do");
}
return {
"init": init;
}
})();
My.Namespaced.SingletonClass.init();
My guess is that the above code would in fact access the correct, inner doSomething function, but I'd like some more security than that. How can I explicitly address the inner/nested function without fear of accidentally calling functions or addressing objects in the scope around my singleton?
Short version: you can't. If doSomething isn't defined as a sibling of init, then JavaScript will search successively broader scopes until it finds a doSomething function, or it runs out of scopes to search.
Longer version: you can prevent this sort of behavior by using a private object to hold your private helper functions, like this:
function doSomething() {
alert("Something I don't want to do");
}
// Assuming My.Namespaced is already defined:
My.Namespaced.SingletonClass = (function() {
var helpers = {};
helpers.doSomething = function() {
alert("Something I want to do");
}
var init = function() {
helpers.doSomething();
}
return {
init: init
}
})();
My.Namespaced.SingletonClass.init();
I'm not sure if it's important that the helper functions are truly siblings (but I don't see why that would particularly matter).
Also keep in mind that My and My.Namespaced need to be defined before you tack on SingletonClass - and there's no need to use JSON-style quoting for keys in the object you're returning.

Categories

Resources