How can I set a Global Variable from within a function - javascript

How can I set a Global Variable from within a function?
$(document).ready(function() {
var option = '';
$("[name=select_option_selected]").change(function() {
var option = $(this).val();
alert(option); // Example: Foo
});
alert(option); // Need it to alert Foo from the above change function
});

Declare it outside the scope of your jQuery onready
var option = '';
$(document).ready(function() {
$("[name=select_option_selected]").change(function() {
option = $(this).val();
alert(option); // Example: Foo
});
alert(option); //This will never be "Foo" since option isn't set until that select list changes
});
if you want to initialize this to the current selected value try this:
var option = "";
var $select_option_selected = null;
$(function() {
$select_option_selected = $("[name='select_option_selected']")
$select_option_selected.change(function() {
option = $(this).val();
});
option = $select_option_selected.val();
});

The Bad Way
As the other answers point out, it's not a good idea to create global variables. And as they point out, you can create a global variable by:
Declaring variable outside of all functions
Initializing your variable without the var keyword
Or, declaring it as a property of the window object: window.options = 'blah';
Using jQuery's Data() Method
But there is a better way of creating a globally accessible value using jQuery (and other libraries). In jQuery, use the data() method to store values associated with DOM elements:
// store 'blah' at document root
$(document).data('mysite.option', 'blah');
// retrieve value
alert($(document).data('mysite.option'));
Notice "mysite"... it is a good idea to namespace your data keys for the same reason it is good to namespace global variables in javascript.

$(document).ready(function() {
var option = '';
$("[name=select_option_selected]").change(function() {
option = $(this).val(); //no declaration of new variable, JavaScript goes to what encloses the function
alert(option); // Example: Foo
});
alert(option); // Need it to alert Foo from the above change function
});

Are you sure you want to? global variables are generally to be avoided. In the browser, window is the global object, so if you do window.option = ..., then option will be available globally.
I highly recommend naming a global variable something more unique than "option", to avoid clobbering existing stuff.
Another option, which I also don't recommend: leave off var
myvariable = 'foo';
If myvariable has never been delcared before, it will be declared as a property on window, making it global. This is generally considered to be (very) bad practice however.

You can use the window. prefix to access a global variable from within the scope of a function
window.option = ...;

Two approaches not mentioned by anybody else, applicable when you: 1. don't have access to the global LexicalEnvironment,10.2.3 and 2. are trying to write code that you wish to support systems wherein a direct reference to the global object15.1 (such as window in the HTML DOM, or GLOBAL in Node[1]) isn't guaranteed:
Make an indirect15.1.2.1.1 call to eval, by wrapping it in a superfluous PrimaryExpression, thus: (1,eval)(...) (the digit and comma operator are meaningless) … and then calling the result thereof. This forces the code to be run in the global execution context.10.4.2
We can then declare10.5 a new variable in the global lexical environment, as suggested above; or, for that matter, do anything else that we desire within that environment:
function global_define(ident, value){
(1,eval) ("var "+ident+"; (function(v){ "+ident+" = v })") (value) }
To be less round-about (and, to boot, avoid the FUD-ridden eval call), we can directly access the global object and set a property4.2 on it, which will then be available as a global variable elsewhere in our code.[2]
Instead of taking the eval approach above and gaining access to the global object via code we've written in the global context, it turns out we can access the global object as the this value10.4.3 within any function that is called with null:
var global = (function(){ return this }).call(null)
global[ident] = value
Phew.
Okay, more reading, for those of you who haven't fainted from specification links and eval calls, yet:
#kangax covers all of the bases quite thoroughly. Seriously, read that if you have any questions I haven't answered here (including those relating to the all-important idiosyncrasies browser support!)
Obviously, the relevant sections of the ECMAScript 5 specification itself, to get an idea for how things are intended to work in an ideal world. No, really though; I know that specifications are a scary idea, but the ES (“JavaScript”) specifications are one of the easiest-to-read and most comprehensible specs I've ever seen. They're truly excellent. Of immediate note, and in no particular order,
10.4, Establishing an Execution Context: Covers how ‘global code’ and ‘eval code’ are handled, specifically.
10.2, Lexical Environments: These describe “where variables are stored.” (The ‘Global Environment’ of interest is one of these.)
10.1, Types of Executable Code: Covers what ‘global code’ and ‘Program’s are.
15.1, The Global Object: Unfortunately, far less relevant than its title makes it sound. Still worth a skim.
[1]: The discussion in other answers, suggesting that exports in Node.js and other CommonJS-compliant systems is somehow related to the global object, about which this question asks, is misleading. In terms of system-design, one might be better suited to using their environment's module tools than poking around on the global object … but that's a discussion for another Stack Overflow post. (=
[2]: For those of you following along in the spec, it's harder to demonstrate that property-members of the global object are accessible as Identifier dereferences. Start with 10.2.1.2 Object Environment Records and 10.2.3 The Global Environment to understand how the global object is linked to an environment, then hop on over to 18.12.3, 18.12.2, and 18.12.1 in that order, collectively describing [[Get]] on the global object.
Nota bene: At no point in this elaboration did I suggest that doing either of these things was a good idea. Or, for that matter, that interacting with the global scope at all is a good idea. Of no relation to the question at hand, but proffered to soothe my own conscience, I add that I wrap all of my own code in a IIFE beginning immediately at the top of the file; this, along with religious application of the var keyword, ensures that I never interact with JavaScript's handling of the global object at all. A huge mess, avoided. You should do that. I said so. I'm smart. (;

just declare a global object
var obj={};
function my_function()
{
obj['newVariable'] = 'someValue';
}
in this way i achieved global variable.

http://jsfiddle.net/Kba5u/
var foo = 'bar';
function changeFooToBaz(){
foo = 'baz';
}
// changeFooToBaz();
console.log(foo); #=> 'bar'
Now, uncomment the call to changeFooToBaz:
var foo = 'bar';
function changeFooToBaz(){
foo = 'baz';
}
changeFooToBaz();
console.log(foo); #=> 'baz'
changeFooToBaz has indeed changed the contents of foo, a variable that was declared at a higher scope than the function.

Related

Why does JavaScript work with some missing syntax? [duplicate]

This question already has answers here:
What is the purpose of the var keyword and when should I use it (or omit it)?
(19 answers)
Closed 7 years ago.
Is "var" optional?
myObj = 1;
same as ?
var myObj = 1;
I found they both work from my test, I assume var is optional. Is that right?
They mean different things.
If you use var the variable is declared within the scope you are in (e.g. of the function). If you don't use var, the variable bubbles up through the layers of scope until it encounters a variable by the given name or the global object (window, if you are doing it in the browser), where it then attaches. It is then very similar to a global variable. However, it can still be deleted with delete (most likely by someone else's code who also failed to use var). If you use var in the global scope, the variable is truly global and cannot be deleted.
This is, in my opinion, one of the most dangerous issues with javascript, and should be deprecated, or at least raise warnings over warnings. The reason is, it's easy to forget var and have by accident a common variable name bound to the global object. This produces weird and difficult to debug behavior.
This is one of the tricky parts of Javascript, but also one of its core features. A variable declared with var "begins its life" right where you declare it. If you leave out the var, it's like you're talking about a variable that you have used before.
var foo = 'first time use';
foo = 'second time use';
With regards to scope, it is not true that variables automatically become global. Rather, Javascript will traverse up the scope chain to see if you have used the variable before. If it finds an instance of a variable of the same name used before, it'll use that and whatever scope it was declared in. If it doesn't encounter the variable anywhere it'll eventually hit the global object (window in a browser) and will attach the variable to it.
var foo = "I'm global";
var bar = "So am I";
function () {
var foo = "I'm local, the previous 'foo' didn't notice a thing";
var baz = "I'm local, too";
function () {
var foo = "I'm even more local, all three 'foos' have different values";
baz = "I just changed 'baz' one scope higher, but it's still not global";
bar = "I just changed the global 'bar' variable";
xyz = "I just created a new global variable";
}
}
This behavior is really powerful when used with nested functions and callbacks. Learning about what functions are and how scope works is the most important thing in Javascript.
Nope, they are not equivalent.
With myObj = 1; you are using a global variable.
The latter declaration create a variable local to the scope you are using.
Try the following code to understand the differences:
external = 5;
function firsttry() {
var external = 6;
alert("first Try: " + external);
}
function secondtry() {
external = 7;
alert("second Try: " + external);
}
alert(external); // Prints 5
firsttry(); // Prints 6
alert(external); // Prints 5
secondtry(); // Prints 7
alert(external); // Prints 7
The second function alters the value of the global variable "external", but the first function doesn't.
There's a bit more to it than just local vs global. Global variables created with var are different than those created without. Consider this:
var foo = 1; // declared properly
bar = 2; // implied global
window.baz = 3; // global via window object
Based on the answers so far, these global variables, foo, bar, and baz are all equivalent. This is not the case. Global variables made with var are (correctly) assigned the internal [[DontDelete]] property, such that they cannot be deleted.
delete foo; // false
delete bar; // true
delete baz; // true
foo; // 1
bar; // ReferenceError
baz; // ReferenceError
This is why you should always use var, even for global variables.
There's so much confusion around this subject, and none of the existing answers cover everything clearly and directly. Here are some examples with comments inline.
//this is a declaration
var foo;
//this is an assignment
bar = 3;
//this is a declaration and an assignment
var dual = 5;
A declaration sets a DontDelete flag. An assignment does not.
A declaration ties that variable to the current scope.
A variable assigned but not declared will look for a scope to attach itself to. That means it will traverse up the food-chain of scope until a variable with the same name is found. If none is found, it will be attached to the top-level scope (which is commonly referred to as global).
function example(){
//is a member of the scope defined by the function example
var foo;
//this function is also part of the scope of the function example
var bar = function(){
foo = 12; // traverses scope and assigns example.foo to 12
}
}
function something_different(){
foo = 15; // traverses scope and assigns global.foo to 15
}
For a very clear description of what is happening, this analysis of the delete function covers variable instantiation and assignment extensively.
var is optional. var puts a variable in local scope. If a variable is defined without var, it is in global scope and not deletable.
edit
I thought that the non-deletable part was true at some point in time with a certain environment. I must have dreamed it.
Check out this Fiddle: http://jsfiddle.net/GWr6Z/2/
function doMe(){
a = "123"; // will be global
var b = "321"; // local to doMe
alert("a:"+a+" -- b:"+b);
b = "something else"; // still local (not global)
alert("a:"+a+" -- b:"+b);
};
doMe()
alert("a:"+a+" -- b:"+b); // `b` will not be defined, check console.log
They are not the same.
Undeclared variable (without var) are treated as properties of the global object. (Usually the window object, unless you're in a with block)
Variables declared with var are normal local variables, and are not visible outside the function they're declared in. (Note that Javascript does not have block scope)
Update: ECMAScript 2015
let was introduced in ECMAScript 2015 to have block scope.
The var keyword in Javascript is there for a purpose.
If you declare a variable without the var keyword, like this:
myVar = 100;
It becomes a global variable that can be accessed from any part of your script. If you did not do it intentionally or are not aware of it, it can cause you pain if you re-use the variable name at another place in your javascript.
If you declare the variable with the var keyword, like this:
var myVar = 100;
It is local to the scope ({] - braces, function, file, depending on where you placed it).
This a safer way to treat variables. So unless you are doing it on purpose try to declare variable with the var keyword and not without.
Consider this question asked at StackOverflow today:
Simple Javascript question
A good test and a practical example is what happens in the above scenario...
The developer used the name of the JavaScript function in one of his variables.
What's the problem with the code?
The code only works the first time the user clicks the button.
What's the solution?
Add the var keyword before the variable name.
Var doesn't let you, the programmer, declare a variable because Javascript doesn't have variables. Javascript has objects. Var declares a name to an undefined object, explicitly. Assignment assigns a name as a handle to an object that has been given a value.
Using var tells the Javacript interpreter two things:
not to use delegation reverse traversal look up value for the name, instead use this one
not to delete the name
Omission of var tells the Javacript interpreter to use the first-found previous instance of an object with the same name.
Var as a keyword arose from a poor decision by the language designer much in the same way that Javascript as a name arose from a poor decision.
ps. Study the code examples above.
Everything about scope aside, they can be used differently.
console.out(var myObj=1);
//SyntaxError: Unexpected token var
console.out(myObj=1);
//1
Something something statement vs expression
No, it is not "required", but it might as well be as it can cause major issues down the line if you don't. Not defining a variable with var put that variable inside the scope of the part of the code it's in. If you don't then it isn't contained in that scope and can overwrite previously defined variables with the same name that are outside the scope of the function you are in.
I just found the answer from a forum referred by one of my colleague. If you declare a variable outside a function, it's always global. No matter if you use var keyword or not. But, if you declare the variable inside a function, it has a big difference. Inside a function, if you declare the variable using var keyword, it will be local, but if you declare the variable without var keyword, it will be global. It can overwrite your previously declared variables. - See more at: http://forum.webdeveloperszone.com/question/what-is-the-difference-between-using-var-keyword-or-not-using-var-during-variable-declaration/#sthash.xNnLrwc3.dpuf

How come no 'var' needed inside js function? [duplicate]

This question already has answers here:
What is the purpose of the var keyword and when should I use it (or omit it)?
(19 answers)
Closed 7 years ago.
Is "var" optional?
myObj = 1;
same as ?
var myObj = 1;
I found they both work from my test, I assume var is optional. Is that right?
They mean different things.
If you use var the variable is declared within the scope you are in (e.g. of the function). If you don't use var, the variable bubbles up through the layers of scope until it encounters a variable by the given name or the global object (window, if you are doing it in the browser), where it then attaches. It is then very similar to a global variable. However, it can still be deleted with delete (most likely by someone else's code who also failed to use var). If you use var in the global scope, the variable is truly global and cannot be deleted.
This is, in my opinion, one of the most dangerous issues with javascript, and should be deprecated, or at least raise warnings over warnings. The reason is, it's easy to forget var and have by accident a common variable name bound to the global object. This produces weird and difficult to debug behavior.
This is one of the tricky parts of Javascript, but also one of its core features. A variable declared with var "begins its life" right where you declare it. If you leave out the var, it's like you're talking about a variable that you have used before.
var foo = 'first time use';
foo = 'second time use';
With regards to scope, it is not true that variables automatically become global. Rather, Javascript will traverse up the scope chain to see if you have used the variable before. If it finds an instance of a variable of the same name used before, it'll use that and whatever scope it was declared in. If it doesn't encounter the variable anywhere it'll eventually hit the global object (window in a browser) and will attach the variable to it.
var foo = "I'm global";
var bar = "So am I";
function () {
var foo = "I'm local, the previous 'foo' didn't notice a thing";
var baz = "I'm local, too";
function () {
var foo = "I'm even more local, all three 'foos' have different values";
baz = "I just changed 'baz' one scope higher, but it's still not global";
bar = "I just changed the global 'bar' variable";
xyz = "I just created a new global variable";
}
}
This behavior is really powerful when used with nested functions and callbacks. Learning about what functions are and how scope works is the most important thing in Javascript.
Nope, they are not equivalent.
With myObj = 1; you are using a global variable.
The latter declaration create a variable local to the scope you are using.
Try the following code to understand the differences:
external = 5;
function firsttry() {
var external = 6;
alert("first Try: " + external);
}
function secondtry() {
external = 7;
alert("second Try: " + external);
}
alert(external); // Prints 5
firsttry(); // Prints 6
alert(external); // Prints 5
secondtry(); // Prints 7
alert(external); // Prints 7
The second function alters the value of the global variable "external", but the first function doesn't.
There's a bit more to it than just local vs global. Global variables created with var are different than those created without. Consider this:
var foo = 1; // declared properly
bar = 2; // implied global
window.baz = 3; // global via window object
Based on the answers so far, these global variables, foo, bar, and baz are all equivalent. This is not the case. Global variables made with var are (correctly) assigned the internal [[DontDelete]] property, such that they cannot be deleted.
delete foo; // false
delete bar; // true
delete baz; // true
foo; // 1
bar; // ReferenceError
baz; // ReferenceError
This is why you should always use var, even for global variables.
There's so much confusion around this subject, and none of the existing answers cover everything clearly and directly. Here are some examples with comments inline.
//this is a declaration
var foo;
//this is an assignment
bar = 3;
//this is a declaration and an assignment
var dual = 5;
A declaration sets a DontDelete flag. An assignment does not.
A declaration ties that variable to the current scope.
A variable assigned but not declared will look for a scope to attach itself to. That means it will traverse up the food-chain of scope until a variable with the same name is found. If none is found, it will be attached to the top-level scope (which is commonly referred to as global).
function example(){
//is a member of the scope defined by the function example
var foo;
//this function is also part of the scope of the function example
var bar = function(){
foo = 12; // traverses scope and assigns example.foo to 12
}
}
function something_different(){
foo = 15; // traverses scope and assigns global.foo to 15
}
For a very clear description of what is happening, this analysis of the delete function covers variable instantiation and assignment extensively.
var is optional. var puts a variable in local scope. If a variable is defined without var, it is in global scope and not deletable.
edit
I thought that the non-deletable part was true at some point in time with a certain environment. I must have dreamed it.
Check out this Fiddle: http://jsfiddle.net/GWr6Z/2/
function doMe(){
a = "123"; // will be global
var b = "321"; // local to doMe
alert("a:"+a+" -- b:"+b);
b = "something else"; // still local (not global)
alert("a:"+a+" -- b:"+b);
};
doMe()
alert("a:"+a+" -- b:"+b); // `b` will not be defined, check console.log
They are not the same.
Undeclared variable (without var) are treated as properties of the global object. (Usually the window object, unless you're in a with block)
Variables declared with var are normal local variables, and are not visible outside the function they're declared in. (Note that Javascript does not have block scope)
Update: ECMAScript 2015
let was introduced in ECMAScript 2015 to have block scope.
The var keyword in Javascript is there for a purpose.
If you declare a variable without the var keyword, like this:
myVar = 100;
It becomes a global variable that can be accessed from any part of your script. If you did not do it intentionally or are not aware of it, it can cause you pain if you re-use the variable name at another place in your javascript.
If you declare the variable with the var keyword, like this:
var myVar = 100;
It is local to the scope ({] - braces, function, file, depending on where you placed it).
This a safer way to treat variables. So unless you are doing it on purpose try to declare variable with the var keyword and not without.
Consider this question asked at StackOverflow today:
Simple Javascript question
A good test and a practical example is what happens in the above scenario...
The developer used the name of the JavaScript function in one of his variables.
What's the problem with the code?
The code only works the first time the user clicks the button.
What's the solution?
Add the var keyword before the variable name.
Var doesn't let you, the programmer, declare a variable because Javascript doesn't have variables. Javascript has objects. Var declares a name to an undefined object, explicitly. Assignment assigns a name as a handle to an object that has been given a value.
Using var tells the Javacript interpreter two things:
not to use delegation reverse traversal look up value for the name, instead use this one
not to delete the name
Omission of var tells the Javacript interpreter to use the first-found previous instance of an object with the same name.
Var as a keyword arose from a poor decision by the language designer much in the same way that Javascript as a name arose from a poor decision.
ps. Study the code examples above.
Everything about scope aside, they can be used differently.
console.out(var myObj=1);
//SyntaxError: Unexpected token var
console.out(myObj=1);
//1
Something something statement vs expression
No, it is not "required", but it might as well be as it can cause major issues down the line if you don't. Not defining a variable with var put that variable inside the scope of the part of the code it's in. If you don't then it isn't contained in that scope and can overwrite previously defined variables with the same name that are outside the scope of the function you are in.
I just found the answer from a forum referred by one of my colleague. If you declare a variable outside a function, it's always global. No matter if you use var keyword or not. But, if you declare the variable inside a function, it has a big difference. Inside a function, if you declare the variable using var keyword, it will be local, but if you declare the variable without var keyword, it will be global. It can overwrite your previously declared variables. - See more at: http://forum.webdeveloperszone.com/question/what-is-the-difference-between-using-var-keyword-or-not-using-var-during-variable-declaration/#sthash.xNnLrwc3.dpuf

Why single var is good in javascript?

Can anyone tell me why use one var declaration for multiple variables and declare each variable on a newline consider is a good programming behavior?
// bad
var items = getItems();
var goSportsTeam = true;
var dragonball = 'z';
// good
var items = getItems(),
goSportsTeam = true,
dragonball = 'z';
It is not considered 'good' or 'bad'. It's a matter of preference.
The guy who built the code quality tool JSLint, Douglas Crockford likes it.
One 'advantage' it might have is that it avoids the possibility of variable hoisting. In JavaScript all var declarations move to the top of their scope automatically.
Here is why Crockford thinks the second option is better:
In languages with block scope, it is usually recommended that variables be declared at the site of first use. But because JavaScript does not have block scope, it is wiser to declare all of a function's variables at the top of the function. It is recommended that a single var statement be used per function. This can be declined with the vars option.
It's a preference, I wouldn't say good or bad. Yes JSLint complains about it, I don't really like how it complains about for loop variables being inline as well. The reason that it was put in JSLint was to prevent possible hoisting confusions.
Also in some cases declaring all of your variables at the top will lead to a slightly smaller file. Consider the following:
var a = 10;
a++;
var b = 20;
After Google Closure being run over it
var a=10;a++;var b=20;
As opposed to this if we pull b's declaration to the top.
var a=10,b;a++;b=20;
The main benefit (aside from style preference, I guess) is that it will prevent you from writing code that suffers from unintended variable hoisting consequences.
Take this example:
var foo = function(){alert('foo');}
function bar(){
foo();
var foo = function(){alert('foobar')};
foo();
}
bar();
By reading this code, the intent of bar appears to be as follows:
Call the outer foo function to alert the string 'foo'.
Create a local variable, foo.
Call the local foo function to alert the string 'foobar'.
In reality, what happens is this:
The local variable foo is hoisted to the top of the bar function.
foo now actually refers to the local variable instead of the outer variable of the same name. But since the local hasn't been assigned yet, its value is undefined. Hence, when you try to invoke foo, you'll get a TypeError.
Nothing. Because you threw an error. That's it. Your code broke.
The arguments for Crockfords preference have been well made and are valid. I am just beginning to return to the first format now however, as I believe that for experienced developers who understand variable hoisting and are not likely to fall foul to it, there are 2 advantages that I can think of:
When new variables are added to the list of definitions, diffing is made easier. This means you are likely to experience fewer merge conflicts (simple though they may be to resolve) and less cognitive load when analysing diffs. For similar reasons I have also been converted to dangling commas, which I would never have expected xD
As #ldsenow identified, it can make searching for variable definitions more simple. You will always be able to search for var <name> and get the result you want and nothing else.

Is using 'var' to declare variables optional? [duplicate]

This question already has answers here:
What is the purpose of the var keyword and when should I use it (or omit it)?
(19 answers)
Closed 7 years ago.
Is "var" optional?
myObj = 1;
same as ?
var myObj = 1;
I found they both work from my test, I assume var is optional. Is that right?
They mean different things.
If you use var the variable is declared within the scope you are in (e.g. of the function). If you don't use var, the variable bubbles up through the layers of scope until it encounters a variable by the given name or the global object (window, if you are doing it in the browser), where it then attaches. It is then very similar to a global variable. However, it can still be deleted with delete (most likely by someone else's code who also failed to use var). If you use var in the global scope, the variable is truly global and cannot be deleted.
This is, in my opinion, one of the most dangerous issues with javascript, and should be deprecated, or at least raise warnings over warnings. The reason is, it's easy to forget var and have by accident a common variable name bound to the global object. This produces weird and difficult to debug behavior.
This is one of the tricky parts of Javascript, but also one of its core features. A variable declared with var "begins its life" right where you declare it. If you leave out the var, it's like you're talking about a variable that you have used before.
var foo = 'first time use';
foo = 'second time use';
With regards to scope, it is not true that variables automatically become global. Rather, Javascript will traverse up the scope chain to see if you have used the variable before. If it finds an instance of a variable of the same name used before, it'll use that and whatever scope it was declared in. If it doesn't encounter the variable anywhere it'll eventually hit the global object (window in a browser) and will attach the variable to it.
var foo = "I'm global";
var bar = "So am I";
function () {
var foo = "I'm local, the previous 'foo' didn't notice a thing";
var baz = "I'm local, too";
function () {
var foo = "I'm even more local, all three 'foos' have different values";
baz = "I just changed 'baz' one scope higher, but it's still not global";
bar = "I just changed the global 'bar' variable";
xyz = "I just created a new global variable";
}
}
This behavior is really powerful when used with nested functions and callbacks. Learning about what functions are and how scope works is the most important thing in Javascript.
Nope, they are not equivalent.
With myObj = 1; you are using a global variable.
The latter declaration create a variable local to the scope you are using.
Try the following code to understand the differences:
external = 5;
function firsttry() {
var external = 6;
alert("first Try: " + external);
}
function secondtry() {
external = 7;
alert("second Try: " + external);
}
alert(external); // Prints 5
firsttry(); // Prints 6
alert(external); // Prints 5
secondtry(); // Prints 7
alert(external); // Prints 7
The second function alters the value of the global variable "external", but the first function doesn't.
There's a bit more to it than just local vs global. Global variables created with var are different than those created without. Consider this:
var foo = 1; // declared properly
bar = 2; // implied global
window.baz = 3; // global via window object
Based on the answers so far, these global variables, foo, bar, and baz are all equivalent. This is not the case. Global variables made with var are (correctly) assigned the internal [[DontDelete]] property, such that they cannot be deleted.
delete foo; // false
delete bar; // true
delete baz; // true
foo; // 1
bar; // ReferenceError
baz; // ReferenceError
This is why you should always use var, even for global variables.
There's so much confusion around this subject, and none of the existing answers cover everything clearly and directly. Here are some examples with comments inline.
//this is a declaration
var foo;
//this is an assignment
bar = 3;
//this is a declaration and an assignment
var dual = 5;
A declaration sets a DontDelete flag. An assignment does not.
A declaration ties that variable to the current scope.
A variable assigned but not declared will look for a scope to attach itself to. That means it will traverse up the food-chain of scope until a variable with the same name is found. If none is found, it will be attached to the top-level scope (which is commonly referred to as global).
function example(){
//is a member of the scope defined by the function example
var foo;
//this function is also part of the scope of the function example
var bar = function(){
foo = 12; // traverses scope and assigns example.foo to 12
}
}
function something_different(){
foo = 15; // traverses scope and assigns global.foo to 15
}
For a very clear description of what is happening, this analysis of the delete function covers variable instantiation and assignment extensively.
var is optional. var puts a variable in local scope. If a variable is defined without var, it is in global scope and not deletable.
edit
I thought that the non-deletable part was true at some point in time with a certain environment. I must have dreamed it.
Check out this Fiddle: http://jsfiddle.net/GWr6Z/2/
function doMe(){
a = "123"; // will be global
var b = "321"; // local to doMe
alert("a:"+a+" -- b:"+b);
b = "something else"; // still local (not global)
alert("a:"+a+" -- b:"+b);
};
doMe()
alert("a:"+a+" -- b:"+b); // `b` will not be defined, check console.log
They are not the same.
Undeclared variable (without var) are treated as properties of the global object. (Usually the window object, unless you're in a with block)
Variables declared with var are normal local variables, and are not visible outside the function they're declared in. (Note that Javascript does not have block scope)
Update: ECMAScript 2015
let was introduced in ECMAScript 2015 to have block scope.
The var keyword in Javascript is there for a purpose.
If you declare a variable without the var keyword, like this:
myVar = 100;
It becomes a global variable that can be accessed from any part of your script. If you did not do it intentionally or are not aware of it, it can cause you pain if you re-use the variable name at another place in your javascript.
If you declare the variable with the var keyword, like this:
var myVar = 100;
It is local to the scope ({] - braces, function, file, depending on where you placed it).
This a safer way to treat variables. So unless you are doing it on purpose try to declare variable with the var keyword and not without.
Consider this question asked at StackOverflow today:
Simple Javascript question
A good test and a practical example is what happens in the above scenario...
The developer used the name of the JavaScript function in one of his variables.
What's the problem with the code?
The code only works the first time the user clicks the button.
What's the solution?
Add the var keyword before the variable name.
Var doesn't let you, the programmer, declare a variable because Javascript doesn't have variables. Javascript has objects. Var declares a name to an undefined object, explicitly. Assignment assigns a name as a handle to an object that has been given a value.
Using var tells the Javacript interpreter two things:
not to use delegation reverse traversal look up value for the name, instead use this one
not to delete the name
Omission of var tells the Javacript interpreter to use the first-found previous instance of an object with the same name.
Var as a keyword arose from a poor decision by the language designer much in the same way that Javascript as a name arose from a poor decision.
ps. Study the code examples above.
Everything about scope aside, they can be used differently.
console.out(var myObj=1);
//SyntaxError: Unexpected token var
console.out(myObj=1);
//1
Something something statement vs expression
No, it is not "required", but it might as well be as it can cause major issues down the line if you don't. Not defining a variable with var put that variable inside the scope of the part of the code it's in. If you don't then it isn't contained in that scope and can overwrite previously defined variables with the same name that are outside the scope of the function you are in.
I just found the answer from a forum referred by one of my colleague. If you declare a variable outside a function, it's always global. No matter if you use var keyword or not. But, if you declare the variable inside a function, it has a big difference. Inside a function, if you declare the variable using var keyword, it will be local, but if you declare the variable without var keyword, it will be global. It can overwrite your previously declared variables. - See more at: http://forum.webdeveloperszone.com/question/what-is-the-difference-between-using-var-keyword-or-not-using-var-during-variable-declaration/#sthash.xNnLrwc3.dpuf

I've Heard Global Variables Are Bad, What Alternative Solution Should I Use?

I've read all over the place that global variables are bad and alternatives should be used. In Javascript specifically, what solution should I choose.
I'm thinking of a function, that when fed two arguments (function globalVariables(Variable,Value)) looks if Variable exists in a local array and if it does set it's value to Value, else, Variable and Value are appended. If the function is called without arguments (function globalVariables()) it returns the array. Perhaps if the function is fired with just one argument (function globalVariables(Variable)) it returns the value of Variable in the array.
What do you think? I'd like to hear your alternative solutions and arguments for using global variables.
How you would use globalVariables();
function append(){
globalVariables("variable1","value1"); //globalVariables() would append variable1 to it's local array.
};
function retrieve(){
var localVariable1 = globalVariables("variable1"); //globalVariables() would return "value1".
};
function retrieveAll(){
var localVariable1 = globalVariables(); //globalVariables() would return the globalVariable()'s entire, local [persistently stored between calls] array.
};
function set(){
globalVariables("variable1","value2"); //globalVariables() would set variable1 to "value2".
};
Is this a Singleton Pattern BTW?
In this specific scenario a function may set a variable at one point in time, and much later another function, maybe when a user submits a form, will need to get that variable. Therefore the first function couldn't pass the variable as an argument to the later function as it would never be called from the first.
Thank you, I appreciate all your help!
The primary reason why global variables are discouraged in javascript is because, in javascript all code share a single global namespace, also javascript has implied global variables ie. variables which are not explicitly declared in local scope are automatically added to global namespace. Relying too much on global variables can result in collisions between various scripts on the same page (read Douglas Crockford's articles).
One way to reduce global variables is to use the YUI module pattern. The basic idea is to wrap all your code in a function that returns an object which contains functions that needs to be accessed outside your module and assign the return value to a single global variable.
var FOO = (function() {
var my_var = 10; //shared variable available only inside your module
function bar() { // this function not available outside your module
alert(my_var); // this function can access my_var
}
return {
a_func: function() {
alert(my_var); // this function can access my_var
},
b_func: function() {
alert(my_var); // this function can also access my_var
}
};
})();
now to use functions in your module elsewhere, use FOO.a_func(). This way to resolve global namespace conflicts you only need to change the name of FOO.
Semantics my boy. Semantics.
Start with one global: myApp = {};
Everything should be in that. The only exception would be your AJAX library (there are some extreme exceptions like working with JSONP callbacks).
There should be very few properties in myApp. You'll want to hold your application properties in containers such as config or settings.
myApp = {
config:{
prop:1
},
settings:{
prop:2
},
widgets:{
List: function(props){},
Item: function(props){}
}
}
Then you may have more properties in lower modules, components, singletons and Class constructors (widgets).
This setup gives you the added benefit of being able to access any property from any other location since you can get it with the myApp global. However, you should use "this" whenever possible because the lookup is faster. And just set the property directly, don't bother with the pseudo getter/setter stuff. If you really need a getter/setter, code it for that specific use.
The reason your example doesn't work is it's too generic and you seem to be looking for an excuse to work in the global space.
And don't get clever with private variables. They're bad too:
http://clubajax.org/javascript-private-variables-are-evil/
Global state causes problems in several areas. One is code reuse. When you access some global state that means the component must be aware of it's environment(something outside of itself). You should avoid this as much as possible, because it makes the component unpredictable.
Say I have an object that accesses your globalVariables function and I want to use it in another page. How do I know to define the globalVariables object or even how to define it? However if you can pass the information into a constructor or as an argument to a function then I can easily determine what is required by the object.
Also when you access or modify the global scope then you risk affecting other objects. This is why libraries like jquery use only a single name on the global scope(the least possible). It lessens the possibility of conflict with other libraries. In other words the global scope is out of your control, so it is dangerous.
Using global variables is generaly speaking a bad practice, regardless of the language of choice. They are not even (easily) allowed to use when at strict mode, which I highly recommend.
Consider this piece of code I found:
if (typeof session != 'undefined' && !data.cart.request_status)
data.input_definitions.passengers =
inflate_passenger(session, data.input_definitions.passengers);
I needed to turn around and ask a felow programmer where did this session variable came from, as no code search showed up where was set.
I turned out another package from the company sets the global variable.
Code it's like a joke: if you need to explain it it's probably not that good.
Workaround using ES6:
If at Node, use import or require to bring the desired stuff into lexical scope, don't let people touch your global environment without you knowing it.
import {Sesssion} from 'api-core';
const Session = require('api-core').session;
If you are at the frontend delivering code for the browser you can't use import unless you transpile your ES6 code using Babel.
Example transpiling using Gulp.js:
// $ npm install --save-dev gulp-babel babel-preset-es2015
// gulpfile.js
const gulp = require('gulp');
const babel = require('gulp-babel');
gulp.task('transpile', () => {
return gulp.src('src/app.js')
.pipe(babel({presets: ['es2015']}))
.pipe(gulp.dest('dist'));
});
// $ gulp transpile
Legacy workaround:
When using ES6 features is not an option the only workaround to using a bunch of global variables, is using only one, and have hope:
// scripts/app.js
var MyApp = {
globals: {
foo: "bar",
fizz: "buzz"
}
};
var ASHIVA_HandsOffNHS = (function() {
// VARIABLES
var my_var = 10;
// PRIVATE FUNCTIONS
function bar() {
console.log(my_var + 5);
}
// PUBLIC OBJECT
myObject = {};
myObject['a_func'] = function() {
my_var += 10;
console.log(my_var);
};
myObject['b_func'] = function() {
my_var = 0;
console.log(my_var);
};
return myObject;
})();
ASHIVA_HandsOffNHS.a_func();
ASHIVA_HandsOffNHS.b_func();
ASHIVA_HandsOffNHS.a_func();
The issue with your solution is that it just makes you code harder to understand while still keeping all the downsides of global variables. The page you linked to covers the problems. The only problem your proposed solution really solves is namespace pollution but at the cost of not being able to see what global variables are declared as easily as the declaration is a function call).
The solution is to write code without global variables. If a function needs a value pass it as a argument.
You really don't want to do this.
As to why see e.g. the top post here: What is the most EVIL code you have ever seen in a production enterprise environment?
As a side note, one can always execute "global" code without littering the place with globals:
(function() {
var notaglobal = 1;
alert(notaglobal);
})();
//notaglobal is not defined in this scope
Other answer most explain with anonymous function as this article mention,
Anonymous functions are difficult to debug, maintain, test, or reuse.
Here are example with normal function. It's easier to read and understand.
/* global variable example */
var a= 3, b= 6;
function fwithglobal(){
console.log(a, b); // 3 6 expected
}
fwithglobal(); // first call
function swithglobal(){
var a=9;
console.log(a, b); // not 3 6 but 9 6
}
swithglobal(); // second call
/* global variable alternative(function parameter) */
function altern(){
var a= 3, b= 6; // var keyword needed
f_func(a,b);
s_func(a,b);
}
function f_func(n, m){
console.log(n, m); // 3 6 expected
}
function s_func(n, m){
var a=9;
console.log(n, m); // 3 6 expected
}
altern(); // only once
Global variables are bad... if left unmanaged!
The potential risks of global variables is as high as the pleasure and productivity gains of having frequently used objects ready to use.
I don't believe one should seek a single alternative. Instead I advocate for one object in charge of managing those globals and as the code base/component matures, refactor them out
One thing not mentioned in the current answers which I think is critical is an understanding of DI and IoC containers. These address many of the problems people try to solve with global variables, but covering related concerns that plain globals can't, like object life cycles.

Categories

Resources