2013-02-19 7 views
1

Извинения за то, что я предполагаю, являются таким основным вопросом, но беглый поиск в JavaScript функций javascript возвращает всевозможные вещи об этом и почему бы не объявлять вещи во всем мире и создавать объекты - все это у меня над головой.Глобальные переменные, функции и Javascript

Я пытаюсь сделать интерактивный геостарт, используя . У меня есть рабочая версия здесь (вроде):

<!-- 
You are free to copy and use this sample in accordance with the terms of the 
Apache license (http://www.apache.org/licenses/LICENSE-2.0.html) 
--> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8" /> 
    <title>Google Visualization API Sample</title> 
    <script type="text/javascript" src="http://www.google.com/jsapi"></script> 
    <script type="text/javascript"> 
    google.load('visualization', '1', {packages: ['geochart']}); 

    var width, height, selectedRegion, resolution; 

    window.onload = function(){ 
     width = 556; 
     height = 400; 
     selectedRegion = 'world'; 
     resolution = 'subcontinents'; 
    }; 

    function drawVisualization() { 
     var data = new google.visualization.DataTable(); 
     data.addColumn('string', 'Region'); 
     data.addColumn('number', 'Value'); 
     data.addRows([ 
     [{v:"005", f:"South America"}, 978.7], 
     [{v:"011", f:"Western Africa"}, 46], 
     [{v:"013", f:"Central America"}, 299], 
     [{v:"014", f:"Eastern Africa"}, 63.9], 
     [{v:"015", f:"Northern Africa"}, 255.7], 
     [{v:"017", f:"Middle Africa"}, 21.4], 
     [{v:"018", f:"Southern Africa"}, 244.5], 
     [{v:"029", f:"Caribbean"}, 76.5], 
     [{v:"030", f:"Eastern Asia"}, 5712.9], 
     [{v:"034", f:"Southern Asia"}, 1275.1], 
     [{v:"035", f:"South-Eastern Asia"}, 639.2], 
     [{v:"039", f:"Southern Europe"}, 777.8], 
     [{v:"053", f:"Australia and New Zealand"}, 272], 
     [{v:"054", f:"Melanesia"}, 6.3], 
     [{v:"057", f:"Micronesia"}, 1.8], 
     [{v:"061", f:"Polynesia"}, 1], 
     [{v:"143", f:"Central Asia"}, 170.3], 
     [{v:"145", f:"Western Asia"}, 834.1], 
     [{v:"151", f:"Eastern Europe"}, 1587.6], 
     [{v:"154", f:"Northern Europe"}, 801.5], 
     [{v:"155", f:"Western Europe"}, 1456.2], 
     [{v:"021", f:"Northern America"}, 4704.1] 
     ]); 

     var options = { 
     displayMode: 'regions', 
     enableRegionInteractivity: 'true', 
     resolution: resolution, 
     region: selectedRegion, 
     height: height, 
     width: width 
     }; 

     var geochart = new google.visualization.GeoChart(
      document.getElementById('visualization')); 

     google.visualization.events.addListener(geochart, 'select', function() { 
     var selection = geochart.getSelection(); 

     if (selection.length == 1) { 
      var selectedRow = selection[0].row; 
      selectedRegion = data.getValue(selectedRow, 0); 
      resolution = "countries"; 
      options.region = selectedRegion; 
      options.resolution = resolution; 
      //alert(resolution); 
      geochart.draw(data, options); 
      } 
     }); 

     geochart.draw(data, options); 
    } 

    google.setOnLoadCallback(drawVisualization); 
    </script> 
</head> 
<body style="font-family: Arial;border: 0 none;"> 
<div id="visualization"></div> 
</body> 
</html> 

Что делает код правильно (и то, что я хочу уточнить, как часть более крупного проекта) является то, что при нажатии на область на карте, он будет изменить параметры карты и перерисовать ее, чтобы увеличить масштаб в этом регионе.

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

Поэтому я хочу разбить свой код на более управляемые куски, куски, которые можно отлаживать индивидуально, дать мне лучшее представление о том, что происходит не так, и вообще сделать весь проект более управляемым на моем конце, так как я далеко от эксперта-программиста (возможно, далекого от начинающего программиста, если честно).

Вот куски, которые я хочу, чтобы разбить его, чтобы:

  1. определения данных (каждый раз опции будут изменены)
  2. определяют параметры (каждый раз опции будут изменены)
  3. отрисовки карты (каждые функции времени 5-7 выполняются)
  4. добавить слушателя (один раз)
  5. функцию, чтобы увеличить на карте (на клик)
  6. функции для уменьшения масштаба на карте (По клику)
  7. функция сброса карты (на клик)
  8. функции для манипулирования данными (каждый раз, когда функции 5-7 выполняются)

Где я бегу к проблемам находится в очень простой вещи , Я могу объявить все мои переменные глобально (без префикса их var), но я думаю, что это, как правило, обескураживает и, вероятно, повредит мне долгое время (особенно, если у меня есть таблица гигантских данных, которая объявлена ​​переменным числом в 10 000 элементов). Если это неверно, пожалуйста, исправьте меня - использование глобальных переменных из моего ограниченного понимания - это плохо, но, может быть, javascript является особенным?

Давайте сосредоточимся на одной из этих функций, а затем, если я пойму, как эта одна функция работает и взаимодействует, тогда я, вероятно, смогу выяснить другие.

Чтобы нарисовать диаграмму, мне нужно иметь две части информации:

  1. Какие данные использовать
  2. Какие варианты использования

Теперь, если я объявляю данные и параметры, как глобальные переменные, я могу с удовольствием манипулировать ими из других функций (спасибо вам большое), но они глобальны. Я не могу понять, как передать вещи в функцию, и возвращать скорректированные данные по мере необходимости.

Например, я могу легко создать рабочую карту следующим образом:

function drawVisualization() { 
    var rawData = new google.visualization.DataTable(); 
    rawData.addColumn('string','Continent'); 
    rawData.addColumn('string','Subontinent'); 
    rawData.addColumn('string','Country'); 
    rawData.addColumn('number','Data'); 
    rawData.addRows([ 
    [{v:"142",f:"Asia"},{v:"145",f:"Western Asia"},{v:"AE",f:"United Arab Emirates"},91.9], 
    // more data in between 
    [{v:"002",f:"Africa"},{v:"014",f:"Eastern Africa"},{v:"ZW",f:"Zimbabwe"},7.8], 
    ]); 

    resetMap(); 

    var data = new google.visualization.DataView(rawData); 
    data.setColumns([resolutionIndex, 3]); 

    var options = { 
    displayMode: displayMode, 
    enableRegionInteractivity: 'true', 
    resolution: resolution, 
    region: region, 
    height: height, 
    width: width 
    }; 

    drawMap(data, options); 

} 

function drawMap(data, options) { 
    var geochart = new google.visualization.GeoChart(document.getElementById('visualization')); 
    geochart.draw(data, options); 
} 

function resetMap() { 
    resolutionArray = ['continents', 'subcontinents', 'countries']; 
    resolutionIndex = 0; 
    previousIndex = 0; 
    previousRegion = 'world'; 
    displayMode = 'regions'; 
    resolution = resolutionArray[resolutionIndex]; 
    region = 'world'; 
    height = '600'; 
    width = '800'; 
} 

Теперь проблема с этим кодом является то, что я должен установить все эти переменные внутри «опцию» переменной как глобальные, и я «Не совсем уверен, что обновление переменных, таких как resolution внутри функции resetMap(), действительно повлияет на значения внутри параметров (мне нужно будет создать еще одну функцию для обновления переменной options?). Также все кажется глобальным, и я не уверен, как я могу передавать переменные взад и вперед и следить за тем, чтобы все они работали вместе, чтобы выполнить свою работу.

Я знаю, что это невероятно длинный пост с, вероятно, чрезвычайно простой концепцией, которая решит его для меня, но я просто не могу обвести вокруг себя голову. Если у кого-то есть общие указатели или описание того, как функции работают в javascript, написанном для истинных новичков (как работают функции, как они определены, как возвращать значения из них и т. Д.), Я был бы очень благодарен.

+0

Возможно, вам нужны все данные в объектах, а затем вы передаете ссылку на объект вокруг, и вы можете читать/записывать данные в объекте. – jfriend00

+0

Не могли бы вы рассказать об этом?Представьте, что вы разговариваете с кем-то, кто был самым продвинутым формальным обучением, был в Бейсике. Потому что вы. Каков процесс фактического выполнения этого и какова концепция этого? Я знаю, что моя переменная 'options' - это объект, и я могу изменять объекты в объекте, но если я передаю объект, могу ли я передать все переменные в нем? Или я полностью в левом поле здесь? – jmac

+1

Ответ на ваш вопрос о том, как писать хорошо структурированный javascript, не сохраняя состояния в глобальных переменных. Я бы предложил хорошую книгу на javascript. Более конкретная часть вашего вопроса заключается в том, что вы создаете объект и добавляете к нему свойства, а когда вы передаете объект вокруг, все свойства идут вместе с ним. – jfriend00

ответ

2

Вы обеспокоены наличием глобальных переменных (это хорошо!), Не зная точно, почему (это плохо!). Основная проблема с ними заключается в том, что в настоящее время очень часто комбинировать сценарии из разных источников на веб-странице. Если все они используют глобальные переменные, вероятность того, что один будет мешать (и сломать) другой из-за столкновения имен, высок. Поэтому лучше всего избегать глобалов.

Для этого первое, что вам нужно понять, это how scope works in JavaScript. Каждая функция создает новую область, поэтому объявленный внутри функции var видна только там. Он также отображается внутри вложенных функций (через closure). Понимание этих двух понятий важно, если вы хотите избежать глобальных переменных.

Существует также простая функция языка, которая может вам помочь: выражение «немедленно вызванное функциональное выражение» (IIFE) может использоваться для обертывания блока кода в его собственной области. Это сфера может быть использована вместо глобального масштаба, чтобы разделять переменные с внутренними функциями, которые могут получить доступ к ним с помощью затворов:

(function(){ 
    // declare common variables here 
    var a = 1, b = 2, c = 3; 

    // any function declare here can access a, b, c 
    function foo() { 
     console.log(a); 
    } 

    // works with anynymous function expressions too 
    document.addEventListener('click', function(e) { 
     alert(b); 
    }); 
}()); 

Это позволяет иметь код, очень похожий на то, что у вас уже есть, но без утечки каких-либо глобал ,

Использование object-oriented js также может помочь вам структурировать код, но это своего рода широкая тема, и я не могу вдаваться в подробности здесь, если вы не зададите более конкретные проблемы, которые у вас есть.

+0

Это именно то, что мне нужно. Спасибо Спасибо спасибо! Я могу объявлять функции внутри функций, а вложенные функции могут наследовать переменные родительских функций! Это означает, что я могу логически отделять свой код от функции, но не должен иметь дело с такой большой суммой, которая передается сумасшедшей переменной. Мальчик, который имеет больше смысла. Благодаря! – jmac

-1

Возможно, вы найдете страницу Code Organization на jQuery Изучение интересного. Большинство концепций по-прежнему применяются, даже если вы не используете jQuery.

+0

Не обижайтесь, но это вступительный абзац: «Когда вы переходите от добавления простых улучшений на свой сайт с помощью jQuery и начинаете разработку полномасштабных клиентских приложений, вам нужно подумать о том, как организовать свой код. В этой главе мы рассмотрим различные шаблоны организации кода, которые вы можете использовать в своем приложении jQuery, и изучите систему управления и создания зависимостей RequireJS. «Это соответствует тому, что я прошу вообще, или даже выгляжу в тот же часовой пояс, что и уровень ответа, который я запрашиваю? Я могу использовать Google, я не могу расшифровать жаргон, которого я не знаю. – jmac

+0

(это, возможно, встретилось чрезмерно резким, и если так я извиняюсь - я не понимаю понятий, если я не понимаю жаргон, и проблема в том, что я, кажется, не понимаю понятия объектов правильно в все) – jmac

Смежные вопросы