Search code examples
javascriptvar

Can you create an object that will be preferred over window when defining a variable with no declaration of var?


Ever since beginning JS a bit over a year ago, I've always had issues with variables that I declare inside of functions but want to access outside the functions. Initially, I would use a script element above all my other scripts with every variable I wanted declared with a var x,y,z;, or a window.x = __; if I didn't want to add it to a list like that. That got annoying to keep up with, so when I learned about not using var to declare things, but still being able to access them, I began to do that. Now I'm seeing things like this, which say to use var for all variables for various reasons. Would it be possible to create an object the variables bubble up to instead of window if there are no previous declarations of the variable, or a substitute for the var declaration? I have the idea to do something like

window.NewVarList = [];
//or is  « var NewVarList = []; »  more appropriate?

function gvar(NewVar,SetVal){
    window.NewVarList[NewVar] = SetVal;
    //or  « NewVarList[NewVar] = SetVal; »
}

but don't know how to make a variable instantly be searched for in NewVarList(using VarInList rather than NewVarList['VarInList']) or how to make gvar x = __; instantly call a gvar(x,__) with the right types for the value I want to set to, instead of everything being a string. Would it be possible to make all variables declared without var instantly go to the window.NewVarList and search for them without needing a NewVarList[VarName]? And if I can't have things instantly bubble up to NewVarList, can I make gvar work without needing the normal parenthesis and arguments? Or should I just go back to defining all my variables outside of my functions? Would it be safe to continue to just leave the var declaration out of my code?


Solution

  • A simpler solution is to put all your code in an IIFE.

    ;function() {
        // all your code goes here
        var x, y, z;
    
        function foo() { ... }
        function bar() { ... }
        ...
    
    }();
    

    Variables you declare at the top-level of the IIFE can be used as global variables in all the other functions, but they won't become part of the window object.

    The only caveat is that none of the functions defined here become global variables, either, so you can't use them in things like onclick="foo()". That shouldn't be a serious problem, since coding like that is considered poor style these days. But if you want to be able to do that, you can define the function like this:

    window.foo = function() { ... };
    

    If you need a number of global names, you should collect them into a single object and put that in window; using a single object avoids polluting the global namespace, which might run into collisions with other libraries that you load (you can see this approach in libraries like jQuery, underscore.js, and lodash).

    In general, when you want to create something to hold named items, you should use an object (or an ES6 Map). While any type of data can be given properties, this is the express purpose of objects.