0

我已经阅读了很多关于 Javascript 范围的内容,并且已经产生了我想要的功能 - 我想我会发布这个问题以在一个地方澄清如何/为什么。

就我而言,我使用的是 Leaflet——一个用于映射的 javascript 库。

我的第一个问题是“L”是什么。

因此,例如,我可以使用以下代码:

current_map = L.map(map_id);

L 代表什么,为什么我可以“通过”它访问功能?

其次,在我的网站上,我有多个不同的地图共享一些通用代码,例如设置地图。

因此,我想开发一些“通用代码”来设置地图并添加标记。

所以我在map_global.js中写了如下代码:

    var current_map;

window.setup_map = function(map_id)
{


    if ($("#"+map_id)[0])
    {

        $("#"+map_id).show();

        current_map = L.map(map_id);

    }
}

然后在我的 map_individual.js 文件中,我简单地写:

map_setup('map_div');

我的地图已经设置好了。

我可以这样做,因为通过在定义函数名称中使用 window 我将函数设置在全局范围内。同样,通过在任何函数之外设置变量 current_map 它也是全局的吗?

这是实现此功能的有效/安全/合理的方式吗?

最后,为什么我不能访问 map_individual.js 中的 current_map?

非常感谢。

汤姆

4

1 回答 1

2

这是一个变量范围的问题。

在概念上将“L”视为名称空间。L 向您公开方法,例如 map、L.map()。

看起来你想公开你的“current_map”变量。在您的 map_global.js 文件中, current_map 当前是一个局部变量 - 因为您使用var声明了它。因此,map_global.js 范围之外的任何内容都无法访问 current_map。

如果您想要一种快速而肮脏的方式来访问 map_individual.js 中的 current_map,您可以通过将全局 window.current_map 设置为 L.map(map_id) 来公开它,因此更改 current_map 变量的范围。

这当然会导致污染全局范围,因此您可以探索的一件事是如何实现“模块化”客户端javascript。一个简单的方法是实现你自己的命名空间。例如,在 map_global.js 中,您可以只公开一个“对象” - 您自己的命名空间 - 并将其附加到窗口。如果将这些方法和变量附加到该“对象”,则可以使用命名空间访问 current_map 和 setup_map(),而不是将所有方法和变量直接附加到窗口 - 全局命名空间 - 这可能很快就会失控。

 function setup_map(){ ...}

 var current_map; 

 window.my_lib = {
   setup_map = setup_map,
   current_map = current_map
 }

所以my_lib.setup_map()my_lib.current_map可以稍后以这种方式访问​​,因为您只使my_lib成为全局的。想象一下,如果 my_lib 公开了十几个函数,其想法是这将更有条理,而不是将所有十几个函数附加到窗口 - 全局命名空间。当您拥有具有相同功能的不同文件/“模块”时,这会派上用场。这样,您可以拥有 my_lib.render() 和 client_lib.render(),而不会相互覆盖,并保持这种分离,作为一种降低覆盖全局命名空间中已有内容的风险的方法。

请注意,导入脚本的顺序也很重要!还有一些库,例如 RequireJS、CommonJS,仅举几个例子,它们试图处理整个模块化事物的依赖方面,值得探索。所以小心行事,希望这会有所帮助!

于 2013-03-20T18:21:50.963 回答