Присвоение значений списку глобальных переменных в JavaScript - PullRequest
1 голос
/ 14 октября 2008

Эй, сейчас я использую jQuery, и у меня есть некоторые глобальные переменные для хранения небольшого количества предварительно загруженного материала AJAX (предварительно загруженного, чтобы страницы выглядели красиво и быстро):


$.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;});

Как вы видите, у нас огромное нарушение принципа СУХОЙ, но ... я не вижу способа это исправить ... есть идеи?

может быть массив?

Ответы [ 6 ]

6 голосов
/ 14 октября 2008

Использование каждого метода jQuery для итерации массива имен страниц, а затем установка глобальной (в области окна) переменной:

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

Обновление: На самом деле, вам даже не нужна "новая функция":

jQuery.each(
    ["viewer", "artists", "instores", "specs", "about"],
    function (page) {
        $.get("content.py?pageName=" + page, function () { window[page] = arguments[0]; });
    }
);
5 голосов
/ 14 октября 2008

Для этого вам не нужно eval() или Function(). Массив, как вы и предполагали, прекрасно справится с этой задачей:

(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)
2 голосов
/ 14 октября 2008

Вы можете избежать eval, используя новую функцию:

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;'));

Это не намного лучше, хотя tbh

0 голосов
/ 17 октября 2008

Большинство из этих предлагаемых решений избегают использования eval . Эта практика получила дальнейшее развитие в « условных обозначениях кода для языка программирования JavaScript » Додугласа Крокфорда, в котором говорится:

"Eval is Evil

Функция eval является наиболее неправильно используемой особенность JavaScript. Избегайте этого.

eval имеет псевдонимы. Не используйте Конструктор функции. "

0 голосов
/ 14 октября 2008

Это не использует eval, хотя и немного более многословно.

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]);

Но один из респондентов сделал хорошую мысль: вам, вероятно, следует попытаться объединить все эти запросы в один, иначе ваш сервер будет подвергаться 6 ударам динамического содержимого при каждом запросе страницы.

0 голосов
/ 14 октября 2008

Вы можете вызывать только один раз эту страницу и возвращать объект json вместо текста

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

и оцени это Поскольку теперь вы вызываете N раз свой сервер, это замедляет все, вам следует пересмотреть свою логику!

PS. когда я писал, я видел ответ Роборга, понимаете, когда вы используете новую функцию, вы используете eval под капотом, так что если вы хотите использовать ее, переходите к ней (в некоторых браузерах тоже быстрее)

...