1

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

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

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

我需要到处访问地图来操作我的地图(使用传单)例如:

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 替代品,而不是让东西全球化?

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

4

1 回答 1

1

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

  1. 您可以将对象用作哈希映射并使用点表示法访问您的变量。该对象仍然是全局的,但至少您可以减少可能发生冲突的全局名称。
  2. 您可以使用namespace.js
  3. 您可以使用闭包来使用伪 oo 样式
  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 闭包,或者将其包装在defineusing dojo.js 或 require.js 中。

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();
于 2013-03-19T02:47:48.773 回答