1
\$\begingroup\$

This might be a dumb question for you advanced developers.

Below is a script on my own website that I want to modify, in order to avoid declaring same variables in each function. I want to avoid declaring variables in the main script structure.

Below code works, still wanted to know if there is a more elegant way to do this.

As Answered below, it's best to enclose everything in an object.

var var1 = document.getElementById("div1");
var var2 = document.getElementById("div2");

function foo1(){
div1.style.display = "none";
}

function foo2(){
div2.style.display = "block";
}
\$\endgroup\$

migrated from stackoverflow.com Aug 15 '12 at 13:33

This question came from our site for professional and enthusiast programmers.

  • 4
    \$\begingroup\$ why have you doubled function function?? Also where is this error? jsfiddle.net/rlemon/fxhK7 I do not see it?? Unless you want to pass around the object, in what you have shown me this does use global variables. in JS you do not need to cast them as such. \$\endgroup\$ – rlemon Aug 13 '12 at 14:44
  • \$\begingroup\$ function function? typo? \$\endgroup\$ – PitaJ Aug 13 '12 at 14:45
  • 2
    \$\begingroup\$ If it's not the function function. You're probably executing the function before you initialize the variables... I think this should work. \$\endgroup\$ – Stephen Sarcsam Kamenar Aug 13 '12 at 14:47
  • \$\begingroup\$ @PitaJ, yes sorry typo \$\endgroup\$ – jacktrades Aug 13 '12 at 14:47
  • \$\begingroup\$ @Xander I make a rollback from PitaJ removal of function function then a rollback again, to PitaJ's removel, when op said it was a typo and I then thought it's was not the meaning of the question. \$\endgroup\$ – Andreas AL Aug 13 '12 at 14:51
4
\$\begingroup\$

You can enclose your variables (and functions) in a closure to restrict your scope, although you then need someway to make those functions callable outside of that closure, e.g.:

(function() {
    var a;

    function increment() {
        a += 1;
    }

    function decrement() {
        a -= 1;
    }

    window.increment = increment;
    window.decrement = decrement;
})();

It's pretty ugly, though. It would be better to enclose the whole thing as an object, e.g.:

function Counter() {
    var count = 0;

    return {
        increment: function() {
            return count++;
        },
        decrement: function() {
            return count--;
        },
        value: function() {
            return count;
        }
    };
};
\$\endgroup\$
  • \$\begingroup\$ Correct, I tried that, wasn't aware of window You need that to make it callable? \$\endgroup\$ – jacktrades Aug 13 '12 at 14:51
  • \$\begingroup\$ @jacktrades yes, that gives those inner functions global references that can be called. I might add a better example, though. \$\endgroup\$ – Alnitak Aug 13 '12 at 14:52
1
\$\begingroup\$
var var1 = "hello";
var var2 = "hello2";

function foo1(){
    var1 += "world";
    var2 += "world2";
}
function foo2(){
    var1 += "2world";
    var2 += "2world2";
}

try that. you had double function keyword , and you forgot braces to close

\$\endgroup\$
  • \$\begingroup\$ Yup, this works for me: jsfiddle.net/Laxc7 \$\endgroup\$ – PitaJ Aug 13 '12 at 14:49
1
\$\begingroup\$

In order to avoid writing those as global variables, put them into a global variable. :)

Before you downvote, let me explain.

Javascript really doesn't have the concept of namespaces, but most big Javascript libraries need to have functions and data accessible to all the Javascript running on a page. They do this by creating one Javascript object and then putting everything in it. jQuery does it with a jQuery object, Google with their google.maps object and you can too.

For your code, create a myApp object (should be a unique name for your application) like so:

myApp = myApp || {}; // No var keyword here, so it's global
myApp.var1 = "hello";
myApp.var2 = "hello2";

function foo1(){
    var var1 = myApp.var1 + "world foo1";
    var var2 = myApp.var2 + "world2 foo1";
}

function foo2(){
    var var1 = myApp.var1 + "world foo2";
    var var2 = myApp.var2 + "world2 foo2";
}

An important thing to remember is to be very careful what code in your application writes to the myApp object. It is still a global and access controls need to be enforced by good design because the code isn't going to do it for you.

\$\endgroup\$
  • \$\begingroup\$ upvoted, helped me. Can you explain me more on the declaration syntax? myApp || {}; \$\endgroup\$ – jacktrades Aug 13 '12 at 15:05
  • \$\begingroup\$ ugh... global scope pollution here. NEVER! I repeat, NEVER do this! \$\endgroup\$ – rlemon Aug 13 '12 at 15:16
  • 1
    \$\begingroup\$ @jacktrades - myApp = myApp || {}; is a way to make sure you won't completely overwrite your global namespace by trying to declare it again. So basically myApp equals the existing myApp if it exists. If it doesn't, it equals an empty object. \$\endgroup\$ – Joseph Erickson Aug 13 '12 at 15:39
  • \$\begingroup\$ @rlemon - Is there a better way? All the major players do it and I always have one object that handles data in my application just like them for objects that need to be accessed by everything in my app, like my main map object, markers I may or may not be showing on the map at the moment, etc. There's no central lookup repository in Javascript, no central database (well, I guess there is for some browsers, is this what you recommend?), where else would you store runtime data and functions for your application? \$\endgroup\$ – Joseph Erickson Aug 13 '12 at 15:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.