42

Which is the right way of declaring a global javascript variable? The way I'm trying it, doesn't work

$(document).ready(function() {

    var intro;

    if ($('.intro_check').is(':checked')) {
        intro = true;
        $('.intro').wrap('<div class="disabled"></div>');
    };

    $('.intro_check').change(function(){
        if(this.checked) {
            intro = false;
            $('.enabled').removeClass('enabled').addClass('disabled');
        } else {
            intro = true;
            if($('.intro').exists()) {
                $('.disabled').removeClass('disabled').addClass('enabled'); 
            } else {
                $('.intro').wrap('<div class="disabled"></div>');
            }
        }
    });
});

console.log(intro);
McGarnagle
  • 101,349
  • 31
  • 229
  • 260
Alex
  • 7,538
  • 23
  • 84
  • 152
  • 3
    putting the `var` keyword makes it local to the function. either remove it or move the declaration outside of the ready function. – Pawan Jun 22 '12 at 08:53

8 Answers8

91

If you're declaring a global variable, you might want to use a namespace of some kind. Just declare the namespace outside, then you can throw whatever you want into it. Like this...

var MyProject = {};
$(document).ready(function() {
    MyProject.intro = "";

    MyProject.intro = "something";
});

console.log(MyProject.intro); // "something"
McGarnagle
  • 101,349
  • 31
  • 229
  • 260
  • Not what the OP asked for, but cleaner. I'd prefer a closure, though, unless the code is modular, and there's a requirement for cross-module access to the global variable. –  Jun 22 '12 at 08:54
  • 1
    @dbaseman, I like your solution because it would solve some problems and improve some of my code (the code It was prebuild, I just improve it)... but for some reason, when I declare `MyProject.intro = "something";` inside DOM Ready function, I keep getting `undefined` as output in `console.log` – Alex Jun 22 '12 at 09:51
  • @w0rldart In the OP code and in the accepted answer, the console log is outside the $(document.ready(...)). So in most of the cases the the console.log will run when the JS is loaded, and AFTER THAT the Ready function will be executed when all the DOM is ready. – d.raev Mar 28 '14 at 08:12
  • Thanks! But why is that I can't console.log() the global variable when I declare it inside $(document).ready ? – ming Dec 08 '18 at 02:15
37

declare this

var intro;

outside of $(document).ready() because, $(document).ready() will hide your variable from global scope.

Code

var intro;

$(document).ready(function() {
    if ($('.intro_check').is(':checked')) {
        intro = true;
        $('.intro').wrap('<div class="disabled"></div>');
    };
    $('.intro_check').change(function(){
        if(this.checked) {
            intro = false;
            $('.enabled').removeClass('enabled').addClass('disabled');
        } else {
            intro = true;
            if($('.intro').exists()) {
                $('.disabled').removeClass('disabled').addClass('enabled'); 
            } else {
                $('.intro').wrap('<div class="disabled"></div>');
            }
        }
    });
});

According to @Zakaria comment

Another way:

window.intro = undefined;

$(document).ready(function() {
    if ($('.intro_check').is(':checked')) {
        window.intro = true;
        $('.intro').wrap('<div class="disabled"></div>');
    };
    $('.intro_check').change(function(){
        if(this.checked) {
            window.intro = false;
            $('.enabled').removeClass('enabled').addClass('disabled');
        } else {
            window.intro = true;
            if($('.intro').exists()) {
                $('.disabled').removeClass('disabled').addClass('enabled'); 
            } else {
                $('.intro').wrap('<div class="disabled"></div>');
            }
        }
    });
});

Note

console.log(intro);

outside of DOM ready function (currently you've) will log undefined, but within DOM ready it will give you true/ false.

Your outer console.log execute before DOM ready execute, because DOM ready execute after all resource appeared to DOM i.e after DOM is prepared, so I think you'll always get absurd result.


According to comment of @W0rldart

I need to use it outside of DOM ready function

You can use following approach:

var intro = undefined;

$(document).ready(function() {
    if ($('.intro_check').is(':checked')) {
        intro = true;
        introCheck();
        $('.intro').wrap('<div class="disabled"></div>');
    };
    $('.intro_check').change(function() {
        if (this.checked) {
            intro = true;
        } else {
            intro = false;
        }
        introCheck();
    });

});

function introCheck() {
    console.log(intro);
}

After change the value of intro I called a function that will fire with new value of intro.

Community
  • 1
  • 1
thecodeparadox
  • 86,271
  • 21
  • 138
  • 164
  • 1
    If my understanding is correct, the question is about declaring a global var inside the `$(document).ready()` function. – Zakaria Jun 22 '12 at 08:53
  • @Zakaria I don't care where the variale is declared, I just need it to be global so I can access it from everywhere – Alex Jun 22 '12 at 08:54
  • @w0rldart you console.log outside of DOM ready function (currently you've) will log `undefined`, but within DOM ready it will give you true/ false. – thecodeparadox Jun 22 '12 at 09:12
  • @thecodeparadox I need to use it outside of DOM ready function, because I will use later on in tinymce to know what to activate or not – Alex Jun 22 '12 at 09:13
  • @w0rldart Your outer console.log execute before DOM ready execute, because DOM ready execute after all resource appeared to DOM i.e after DOM is prepared, so I think you'll always get absurd result. – thecodeparadox Jun 22 '12 at 09:16
  • @w0rldart I have update my answer, I think my last part will work for you – thecodeparadox Jun 22 '12 at 09:34
16

JavaScript has Function-Level variable scope which means you will have to declare your variable outside $(document).ready() function.

Or alternatively to make your variable to have global scope, simply dont use var keyword before it like shown below. However generally this is considered bad practice because it pollutes the global scope but it is up to you to decide.

$(document).ready(function() {
   intro = null; // it is in global scope now

To learn more about it, check out:

Sarfraz
  • 377,238
  • 77
  • 533
  • 578
  • For some reason, it won't go! When I try the `alert(intro)` or `console.log(intro)` it keeps returning undefined. I tried almost all the solutions proposed in this thread – Alex Jun 22 '12 at 09:10
  • @w0rldart: There should be something else wrong. Make sure that you are not re-defining that variable somewhere else and also beware of javascript hoisting: http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting. And try your `console.log` command inside the `ready` handler which is where you manipulate the `intro` variable. – Sarfraz Jun 22 '12 at 09:12
7

Use window.intro inside of $(document).ready().

xdazz
  • 158,678
  • 38
  • 247
  • 274
  • 2
    @OliverWeiler global variables per say aren't but being explicit about when you're modifying a global variable is pretty good practice I'd say... – Esailija Jun 22 '12 at 08:55
3

You can define the variable inside the document ready function without var to make it a global variable. In javascript any variable declared without var automatically becomes a global variable

$(document).ready(function() {
    intro =  "something";
});

although you cant use the variable immediately, but it would be accessible to other functions

Joshua
  • 818
  • 11
  • 12
2

like this: put intro outside your document ready, Good discussion here: http://forum.jquery.com/topic/how-do-i-declare-a-global-variable-in-jquery @thecodeparadox is awesomely fast :P anyways!

 var intro;

$(document).ready(function() {



    if ($('.intro_check').is(':checked')) {
        intro = true;
        $('.intro').wrap('<div class="disabled"></div>');
    };

    $('.intro_check').change(function(){
        if(this.checked) {
            intro = false;
            $('.enabled').removeClass('enabled').addClass('disabled');
        } else {
            intro = true;
            if($('.intro').exists()) {
                $('.disabled').removeClass('disabled').addClass('enabled'); 
            } else {
                $('.intro').wrap('<div class="disabled"></div>');
            }
        }
    });
});
Tats_innit
  • 33,991
  • 10
  • 71
  • 77
2

Unlike another programming languages, any variable declared outside any function automatically becomes global,

<script>

//declare global variable
var __foo = '123';

function __test(){
 //__foo is global and visible here
 alert(__foo);
}

//so, it will alert '123'
__test();

</script>

You problem is that you declare variable inside ready() function, which means that it becomes visible (in scope) ONLY inside ready() function, but not outside,

Solution: So just make it global, i.e declare this one outside $(document).ready(function(){});

Yang
  • 8,580
  • 8
  • 33
  • 58
1

Use window.intro = "value"; inside the ready function. "value" could be void 0 if you want it to be undefined

Esailija
  • 138,174
  • 23
  • 272
  • 326