This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to avoid global variables in JavaScript?
I'm looking for some advice on how best to manage global variables in JavaScript.
Consider the following:
foo = 1;
bar = 2;
// Update our global variable
function doStuff (newFooValue) {
foo = newFooValue
}
// Update a global based on a condition
function doMoreStuff () {
if (bar == 3) {
foo = 1;
}
}
In both cases, our functions are accessing global variables internally, which feels ugly to me. From what I've read, we want to avoid globals as much as possible to avoid clogging up the global name space.
So is creating a structure for our globals all that we need?
For example,
var myPage = {}
myPage.foo = 1;
myPage.bar = 2;
I suppose this solves the global namespace collision problem, but I am still accessing the global scope from within my methods.
What should I do?
To avoid global namespace pollution you should wrap your code in an Immediately Invoked Function Expression (IIFE). JavaScript variables have functional scope so they only exist within the function they're declared in.
(function () {
//these variables only exist within the outer function
var foo,
bar;
foo = 1;
bar = 2;
//these functions only exist within the outer function
function fizz() {
return foo + bar;
}
function buzz() {
return foo - bar;
}
}());
The above example is pretty useless, as all the variables and functions are encapsulated and won't be usable externally. Any functions/variables that need to be global should be manually added to the global object:
(function (g) {
//not repeating code from above, pretend it's here
//make the functions globally accessible
g.fizz = fizz;
g.buzz = buzz;
}(this));
Wrap it in a class maybe?
var myPage = {}
myPage.foo = 1;
myPage.bar = 2;
myPage.doStuff = function(newFooValue) {
this.foo = newFooValue;
}
You would just use one spot in the global scope then.
You should avoid this but if you need to address the global scope then you will do it.
If you are asking about design patterns you would have to be more precise.
If you have two functions named doStuff and doMoreStuff it is a very hard thing to design.
Related
The var keyword in javascript causes a variable to be stored in the local scope. Without var variables belong to the global scope. What about functions? It's clear what happens when functions are declared like variables
var foo = function() {...}
but what scope does
function foo() {...}
belong to?
EDIT:
I realized I didn't ask quite the right question so as a follow up. In the outer most nesting is there a difference between the above two declarations and the following declaration?
foo = function() {...}
It belongs to the current scope, always. For example:
// global scope
// foo is a global function
function foo() {
// bar is local to foo
function bar() {
}
}
Regarding your second question, this:
foo = function() {...}
is an anonymous function expression assigned to a global variable (unless you're running is strict mode, then foo would be undefined). The difference between that and function foo() {} is that the latter is a function declaration (versus a variable declaration, which is assigned an anonymous function expression).
You might be interested in this excellent article about function declarations and function expressions: Named function expressions demystified.
Function declarations are always local to the current scope, like a variable declared with the var keyword.
However, the difference is that if they are declared (instead of assigned to a variable) their definition is hoisted, so they will be usable everywhere in the scope even if the declaration comes in the end of the code. See also var functionName = function() {} vs function functionName() {}.
Noteworthy distinction taking implicit globals into account:
var foo = function() {
// Variables
var myVar1 = 42; // Local variable
myVar2 = 69; // Implicit global (no 'var')
// Functional Expressions
var myFn1 = function() { ... } // Local
myFn2 = function() { ... } // Implicit global
function sayHi() {
// I am a function declaration. Always local.
}
}
Hopefully that clarifies a little. Implicit globals are defined if you forget a var before your assignment. Its a dangerous hazard that applies to variable declarations and functional expressions.
Your first example (var foo = function() {...}) is called an anonymous function. It is dynamically declared at runtime, and doesn't follow the same rules as a normal function, but follows the rules of variables.
According to the Closures concept it will store the variables of the outer lexical environment for future execution of its inner function. For example:
function makeYounger(age) {
function b() {
console.log("Original age is :" + age);
}
b();
return(function() {
return age / 2;
});
}
var displayAge = makeYounger(20);
console.log(displayAge());
In the above scenario, age is preserved by the Javascript engine to execute the inner function present in the return method.
Here comes the IIFE:
(function(window) {
var greeting = "Hello";
var fNameSpace1 = {
name : "Appu",
callName : function() {
console.log(greeting + fNameSpace1.name);
}
};
window.doer = fNameSpace1;
}) (window);
fNameSpace1.callName(); //To execute the inner function
In the above scenario according to the closures concept the variables greeting and fNameSpace1.name will be stored for future execution of the callname() function. Instead we are making use of the window object. I am confused why we are going with window if we have closures?
IIFE is useful to avoid global variable pollution when multiple functions are accessing a global variable
Closure functions are helpful when working with a local variable.
Difference between closures and IIFE's in javascript
An IIFE is just one specific way to A) Create a closure over the context in which it's defined, and B) Create a context in which to create other closures.
My question is what is the exact use of window object in this scenario if the javascript engine already stores fNameSpace1 object.Why are we creating a reference using window?
So it can be used outside the IIFE, by referring to it via the doer global that window.doer = ... creates.
There are dozens of different ways to do this. One of them does it by assigning to window like that. Another does it by returning the value and using a var statement:
var doer = (function() {
// ...
return fNamespace1;
})();
but again, there are dozens of different formations. The author of that particular one just preferred to write to a property on window as the way to create the global.
Using Node.
Trying to avoid global vars, but I need to share a variable(integer) between two functions that are not nested. Both functions are declared directly under the global scope.
Is something like this considered a good practice for what I'm trying to accomplish? If not, is there a better pattern to follow?
function doStuffWithDataFromEventListener(){
var a = inner2().num;
}();
var fakeListener = function(){ //make believe event listener that is only called once.
var num = 7;
return {num: num};
};
Use the module pattern:
// Global scope
(function(){
// Function (module) scope
var x = 5; // Module level (not global) variable
function a(){
return ++x;
}
function b(){
return ++x;
}
a(); // 6
b(); // 7
}());
There are several ways to control/prevent global variables is to create a closure function and put all your code in there. All code will be in the DOM as an anonymous function. You can also give that function a name so it will be easier to test. You can also create a global object and attach all your methods, variables, and properties onto that. I'm sure you've seen this before.
var myAppObj = myAppObj || {};
myAppObj.name = "tommy";
MyAppObj.odStuffFunc = function() {
// do stuff
};
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What advantages does using (function(window, document, undefined) { … })(window, document) confer?
I'm increasingly seeing code like this in libraries I've been using:
(function (window) {
var Foo = function () {
}
window.Foo = Foo;
})(window);
The argument I've seen for doing this is to avoid working in the global scope when creating (pseudo) classes. But, correct me if I'm wrong, I always understood that window IS the global scope. I believe, when you create a global variable, you are really only adding a property to window anyway... Unless this is changing for ES5 strict?
So, basically, what's the point? The only benefit I can see to code organised like this is if you wanted to easily change the namespace of your classes at a later date by passing in an argument other than window.
Infact, strict mode throws an exception if you forget to use var for any variable declaration. But that works even without using an outer closure.
Using this pattern is much more for protecting yourself from the outside javascript world. For instance, some other script overwrites window.undefined or any other variable, you can grab the value within that closure to savely access it from within.
For instance
(function _myApp( win, doc, undef ) {
// app code
}( this, this.document ));
Also, when declaring variables with var, or creating function declarations, those are always stored within the current Activation Object respectively the Lexical Environment Record. That means, without using a Function context, you can easily overwrite methods and variables from some other point, because all of those would get stored in the current Context (which would be the global one)
So:
(function _myApp( win, doc, undef ) {
var myVar = 42;
function myFunc() {
}
}( this, this.document ));
(function _myModule( win, doc, undef ) {
var myVar = 42;
function myFunc() {
}
}( this, this.document ));
This works because of closure and Context, but if you would use the same code, without the Function Context, we would obviously overwrite our myVar and myFunc. This could happen from everywhere, within the same file or in another loaded script.
As evil as global variables are, you need to have atleast one or there's no way to access your script. The code you provided is one way to create that one global variable. I prefer this way:
window.Foo = (function () {
var func = function () {
// ...
};
return {
func: func
};
})();
Your're right, but the difference is that the code inside of the function acts like an automatic init function.
(function (window) {
var Foo = function () {
}
var Bar = 69; // not in global scope
window.Foo = Foo; // in global scope
})(window);
As opposed to
var Foo = function () { // in global scope
}
var Bar = 69; // in global scope
and
var Foo = function () { // in global scope
}
function init () {
var Bar = 69; // not in global scope
}
init();
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Confused by Javascript's variable scope
For example, this is my JavaScript code:
var foo = 'Originalvalue';
var foo = 'Nextvalue';
alert(foo); // Nextvalue
So then, now I am sure writing var in front of an already-declared variable just simply is nullified and of no use to the program.
But then consider this program:
var foo = 'Originalvalue';
function duhfoo() {
var foo = 'Newbievalue';
}
duhfoo();
alert(foo); // Originalvalue
Then, from the logic explained in my first example, the value should be 'Originalvalue', as there is already a variable called foo. Then why is it like so?
In Javascript there are two kinds of variables: local variables and global variables.
When using var outside of functions you are declaring a global variable and the same happens if you don't use var at all. Writing
foo = "first";
at top level (outside any function) is the same as var foo = "first".
When inside a function however things are different, and the keyword var discriminates between local and global variables:
var foo = "first";
var bar = "second";
function f()
{
var foo = "third"; // local
bar = "fourth"; // global
}
f();
alert([foo, bar]); // output will be first,fourth
In other words when you use var inside a function the variable will be a different one with the same name, visible only by code written inside the boundaries of the function.
Please note that the boundary is determined by the function, and not the braces {...}. If you have nested blocks and use another var declaration inside the blocks the variable will be the same and this is different from what happens in other languages like Java, C or C++.
The only way to create a scope is to define a function (including a function inside a function).
Another very important thing to remember in Javascript (especially if having been exposed to similar-looking languages in which this concept is not present like Java, C or C++) is the idea of "capture"/"closure"...
var foo = "first";
function f()
{
// Local variable
var foo = "second";
function g()
{
// This is the local foo of f, not the global
// one even if there is no "var" declaration
// inside this nested scope
return foo;
}
return g;
}
var nested_function = f();
alert([foo, nested_function()]); // output will be first,second
Basically a local variable can "outlive" the function that defined it, by being used by other functions that are said to "capture" that variable. A function that captures one or more variable is called "closure".
In other words a local variable is only visible inside the body of the function, but it may live longer than then function like it happens for the local foo of last example in which the variable survived after returning from f because it has been captured by closure g.
well variable foo inside duhfoo clearly states that its scope is duhfoo() method and not global.
Because
(From MDN)
var has the following properties
function-scoped
hoist to the top of its function
redeclarations of the same name in the same scope are no-ops
Please read this for more information on this subject.