[英]Global Variables, Functions and Javascript
抱歉,我认为这是一个基本问题,但是谷歌对javascript函数的粗略搜索会返回有关“ this”的各种信息,以及为什么不全局声明内容并创建对象-所有这些都超出了我的脑海。
我正在尝试使用google-visualization创建交互式geochart。 我在这里有一个工作版本(有点):
<!--
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>
代码正确执行的功能(以及我想作为较大项目的一部分进行完善的功能)是,当您单击地图上的某个区域时,它将更改地图的选项并重新绘制,以进一步放大该区域。
这是出色的,但是上面是一个庞大的函数,在函数内部带有处理函数。 这将变得非常笨拙,因为我必须添加诸如缩小,重置地图以查看整个世界的内容,还必须根据所选区域调整更大的数据集(上面的示例将放大区域,然后当前不显示任何数据)。
因此,我想将我的代码分解为更易于管理的块,这些块可以单独调试,让我对哪里出了问题有更好的了解,并且由于我离专家程序员很远,因此总体上可以使整个项目更易于管理。 (说实话,可能与新手程序员相去甚远)。
这是我想细分的块:
我遇到问题的地方是最基本的东西。 我可以全局声明所有变量(而不用var
前缀),但我认为通常不建议这样做,并且可能会长期损害我的利益(尤其是如果我有一个巨大的数据表,该表以10,000个元素可变地声明)。 如果这是错误的,请纠正我-从我的有限理解中使用全局变量是一件坏事,但是javascript可能很特殊吗?
让我们专注于这些功能之一,然后,如果我了解一个功能的工作原理和交互方式,那么我可能可以找出其他功能。
要绘制图表,我需要掌握两点信息:
现在,如果我将数据和选项都声明为全局变量,则可以从其他函数中愉快地操作它们(非常感谢),但是它们是全局的。 我不知道如何将事物传递给函数,并根据需要返回调整后的数据。
例如,我可以轻松创建一个工作图,如下所示:
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';
}
现在,这段代码的问题是,我必须将“ options”变量中的所有这些变量都设置为全局变量,而且我不太确定更新resetMap()
函数中的诸如resolution
之类的变量实际上会影响options中的值(我是否需要再创建一个函数来更新options
变量?)。 同样,一切似乎都是全局的,我不确定如何来回传递变量,并确保它们一起工作以完成工作。
我知道这是一篇篇幅非常长的文章,可能有一个非常简单的概念可以为我解决,但是我实在无法解决这个问题。 如果有人有任何通用指针,或者是为真正的初学者写的关于JavaScript中函数如何工作的描述(函数如何工作,如何定义它们,如何从中返回值等),我将不胜感激。
您担心没有全局变量(很好!)而没有全局变量(很好!)。 它们的主要问题是,如今在网页中组合来自各种来源的脚本非常普遍。 如果它们全部使用全局变量,则由于命名冲突,一个人将干扰(并破坏)另一个人的机会很高。 因此,最佳做法是避免全局变量。
为此,您首先要了解的是范围在JavaScript中是如何工作的 。 每个函数都会创建一个新的作用域,因此在函数内部声明的var
仅在此处可见。 在嵌套函数内部(通过闭合 )也可见。 如果要避免使用全局变量,那么必须了解这两个概念。
还有一个简单的语言功能可以为您提供帮助:“立即调用的函数表达式”(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);
});
}());
这样一来,您可以拥有与已拥有的代码非常相似的代码,而且不会泄漏任何全局变量。
使用面向对象的js还可以帮助您构建代码,但这是一个广泛的主题,除非您询问有关它的更多具体问题,否则我在这里不做任何详细介绍。
您可能会发现jQuery Learning上的“代码组织”页面很有趣。 即使您不使用jQuery,大多数概念仍然适用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.