17

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    
});
Phill Pafford
  • 83,471
  • 91
  • 263
  • 383
  • 2
    Avoid global variables - consider using jQuery's data() method as I mention in my answer. – typeof Apr 05 '11 at 18:55

8 Answers8

25

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();
});
hunter
  • 62,308
  • 19
  • 113
  • 113
  • 2
    Technically, if you don't declare it, the browser will declare it globally, but this is unsafe and will not pass strict mode in the future (coming soon to a browser near you =D) – beatgammit Apr 05 '11 at 18:36
  • Thanks, it was the extra var inside the change() that was making it local to the function – Phill Pafford Apr 05 '11 at 18:54
6

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.

typeof
  • 5,812
  • 2
  • 15
  • 19
  • I disagree that setting global data on the document is any better than creating a global variable. Still has all the problems of globals, plus it requires a lot more typing – Ruan Mendes Sep 12 '11 at 20:18
  • I see what you're saying, but the data method is not doing what you think. See this answer for an explanation: http://stackoverflow.com/questions/5905994/i-know-its-bad-to-store-data-in-the-dom-but-why – typeof Sep 16 '11 at 21:20
  • My comment has nothing to do with the implementation of `$.data`, you don't know how I think `$.data` is implemented. The problem is that something that is associated with the whole document, suffers from the same problems as creating a global variable, everybody accessing and changing it, name collisions. The broader you scope your stuff, the more likely you are to run into problems – Ruan Mendes Sep 16 '11 at 21:29
4
$(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    
});
Zirak
  • 38,920
  • 13
  • 81
  • 92
3

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:

  1. 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) }
    
  2. 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:

  1. @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!)
  2. 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,


[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. (;

ELLIOTTCABLE
  • 17,185
  • 12
  • 62
  • 78
3

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.

Matt Greer
  • 60,826
  • 17
  • 123
  • 123
3

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

window.option = ...;
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
1

just declare a global object

var obj={};
function my_function()
{
 obj['newVariable'] = 'someValue';
}

in this way i achieved global variable.

1

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.

Starkers
  • 10,273
  • 21
  • 95
  • 158