【问题标题】:JavaScript Globals alternativesJavaScript Globals 替代品
【发布时间】:2013-03-07 10:17:28
【问题描述】:

我正在使用一个框架(流星,但我猜的问题并不重要),它提供了单独的功能..

我的问题是我意识到我正在使用越来越多的全局变量以使它们在这些函数之间可访问。例如 ma​​p 对象:

Meteor.startup(function () {
  map = L.map('map_canvas').locate({setView: true, maxZoom: 21});
  L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
      attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
  }).addTo(map);
});

我需要在任何地方访问 ma​​p 来操作我的地图(使用 Leaflet) 例如:

Template.messages.events({
  'click .delete-message': function (e,t) {
    e.stopPropagation();
    removeItem(e.target.id);
  },
  'click .message': function (e,t) {
    console.log('event clicked');
    map.setView([e.target.getAttribute('data-lat'),e.target.getAttribute('data-lng')], 16);
  }
});

当我想创建一个我想在不同地方使用的标记对象时,我遇到了同样的问题......

是 Meteor 是以这种方式构建的,还是有更合适/干净的 JS 替代方案而不是使东西全球化?

编辑感谢您的回答,您能否添加一个代码示例,例如使用您提到的模式之一,但基于我的代码?这样我可以更好地理解它。

【问题讨论】:

  • 你可能想看看这个其他的,可能类似的question/answer thread
  • 除了“命名空间”选项之外,您还可以对所有代码使用单个闭包(也称为模块模式),以便您的函数可以使用变量,但其他人不能使用。
  • This article 很棒。
  • @jahroy 确实如此。
  • @大家我更新了我的问题..为了将理论付诸实践,有一个基于我的代码的例子会有很大帮助?

标签: javascript oop global-variables closures


【解决方案1】:

有很多方法可以使 js 变量和函数不是全局的。

  1. 您可以将对象用作哈希映射,并使用点符号访问您的变量。该对象仍然是全局的,但至少您可以减少可能发生冲突的全局名称。
  2. 您可以使用 namespace.js
  3. 您可以使用 pseudo-oo style using closures
  4. 您可以使用 coffeescript
  5. 除了 namespace.js,很多像 dojo.js 这样的框架都允许使用模块。
  6. 可能还有许多其他选项。

Dojo.js 和我认为 require.js 鼓励模块化设计。 (除其他外)命名空间非常容易包含和使用,并且可以通过最少的代码更改来解决您的问题。我过去曾使用它从全局风格转向更多面向对象的风格。

选项 1,哈希图

var GKApp = new Object();
GKApp.map = blah;
GKApp.size = 1;
GKApp.doSomethingWithMap = function() {
    GKApp.map.blah();
}
// Now the only global is GKApp.
// Later, make the call. 
GKApp.doSomethingWithMap.call();

选项 3,闭包

您可以使用如下所示的纯 javascript 闭包,或者使用 dojo.js 或 require.js 将其包装在 define 中。

GKApp = function(pmap) {
    // dbg.log("GKApp constructor.");
    // You can consider the closure to 'begin' here.

    // ********************************************************
    // @private variables:
    // ********************************************************
    var map = pmap;

    /**
     * @privileged method which has access to variables in the closure.
     * These variables are not available outside of the closure.
     * An anonymous function has access to variables in the outer scope or, the closure.
     */
    this.doSomethingWithMap = function() {
        map.blah();
    };
};

// Later, instantiate an object and use it. 
var gkApp = new GKApp(map);
gkApp.doSomethingWithMap();

【讨论】:

  • 不止于此。例如,散列在不使用“散列”一词表示关联数组的语言的上下文中意味着其他东西。它意味着一个计算值,可以用作一条数据的标识符。例如 MD5 和 CRC32 就是散列的例子。另一方面,实际调用对象也有助于让新手程序员了解 js 中对象的动态特性。
  • Jessemon 感谢您的详细回答。我之前读过关于模块化设计和闭包的内容,但现在我实际尝试实现我有更实际的问题:首先想到的是,闭包应该限制变量的范围。到目前为止,一切都很好。但我要问的是如何在不污染全局范围的情况下安全地在不同函数之间共享变量。我想使用模块化模式会有所帮助 - 整个要点是使用“return” - 还是我错了?
  • 我有地图对象 - 这基本上是我的主要问题,因为我想在不同的功能中访问它..
猜你喜欢
  • 2012-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多