简体   繁体   中英

Assigning values to a list of global variables in JavaScript

Hey right now I'm using jQuery and I have some global variables to hold a bit of preloaded ajax stuff (preloaded to make pages come up nice and fast):


$.get("content.py?pageName=viewer", function(data)
    {viewer = data;});
$.get("content.py?pageName=artists", function(data)
    {artists = data;});
$.get("content.py?pageName=instores", function(data)
    {instores = data;});
$.get("content.py?pageName=specs", function(data)
    {specs = data;});
$.get("content.py?pageName=about", function(data)
    {about = data;});

As you can see, we have a huge violation of the DRY principle, but... I don't really see a way to fix it... any ideas?

maybe an array?

Using the jQuery each method to iterate through an array of page names and then setting a global (in window scope) variable:

jQuery.each(
    ["viewer", "artists", "instores", "specs", "about"],
    function (page) {
        $.get("content.py?pageName=" + page,
            new Function("window[" + page + "] = arguments[0]"));
    }
);

Update: Actually, you don't even need the "new Function":

jQuery.each(
    ["viewer", "artists", "instores", "specs", "about"],
    function (page) {
        $.get("content.py?pageName=" + page, function () { window[page] = arguments[0]; });
    }
);

You don't need eval() or Function() for this. An array, as you suspected, will do the job nicely:

(function() // keep outer scope clean
{
   // pages to load. Each name is used both for the request and the name
   // of the property to store the result in (so keep them valid identifiers
   // unless you want to use window['my funky page'] to retrieve them)
   var pages = ['viewer', 'artists', 'instores', 'specs', 'about'];

   for (var i=0; i<pages.length; ++i)
   {
      // "this" refers to the outer scope; likely the window object. 
      // And will result in page contents being stored in global variables 
      // with the same names as the pages being loaded. We use the with({})
      // construct to create a local scope for each callback with the
      // appropriate context and page name.
      with ({context: this, pageName: pages[i]})
         $.get("content.py?pageName=" + pageName, function(data)
            {context[pageName] = data;});
   }

})(); // close scope, execute anonymous function

// at this point, viewer, artists, etc. are populated with page contents 
// (assuming all requests completed successfully)

You can avoid eval using new Function:

var names = ['viewer', 'artists', 'instores', 'specs', 'about'];
for (var i = 0; i < names.length; i++)
   $.get("content.py?pageName=" + names[i], new Function('data', names[i] + ' = data;'));

It's not a lot better though tbh

You can call only one time that page, and returning a json object instead of text

{
viewer:'me',
artists:'you',
instores:'instores',
specs:'specs',
about:'about'
}

and eval that Since now you're calling N times your server, this slow down all, you should reconsider your logic!

PS. as I write i saw the RoBorg answer, you see, when using new Function you are using eval under the hood, so if you want to use it go for it (in some browser is faster too)

This doesn't use eval, though it's a little more wordy.

function get_content(name){
   $.get("content.py?pageName=" + name, function(data){ window[name] = data;});
}

var names = ['viewer', 'artists', 'instores', 'specs', 'about'];
for (var i = 0; i < names.length; i++)
    get_content(names[i]);

But one of the of answerers made a good point, you should probably try and combine all these requests into one otherwise your server will be hit 6 times for dynamic content on each request of the page.

Most of these proposed solutions avoid the use of eval . That practice is further reinforced in Doduglas Crockford's " Code Conventions for the JavaScript Programming Language " which says in part

"eval is Evil

The eval function is the most misused feature of JavaScript. Avoid it.

eval has aliases. Do not use the Function constructor."

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM