流星中的全局变量

时间:2014-12-16 16:18:24

标签: javascript node.js meteor scope

我有

var Schemas = {};

Meteor.isClient && Template.registerHelper("Schemas", Schemas);

Schemas.Person = new SimpleSchema({
  fullName: {
    type: String,
    index: 1,
    optional: true,
  },
  email: {
    type: String,
    optional: true
  },
  address: {
    type: String,
    optional: true
  },
  isActive: {
    type: Boolean,
  },
  age: {
    type: Number,
    optional: true
  }
});

在一个文件中

var Collections = {};

Meteor.isClient && Template.registerHelper("Collections", Collections);

Persons = Collections.Persons = new Mongo.Collection("Persons");
Persons.attachSchema(Schemas.Person);

在另一个档案中。

我收到错误ReferenceError: Schemas is not defined。很明显,我必须在Schemas文件中定义collections.js而不是将它们分开。但Meteor如何在单独的文件中使用代码?我可以访问一些对象和变量,而其他对象和变量是无法访问的。

4 个答案:

答案 0 :(得分:57)

以经典JavaScript方式定义变量时:

var someVar = 'someValue';

.js文件的根目录下,Meteor使用IIFE将其范围限定为文件。

如果你想定义一个全局变量,就不要写var,给出:

someVar = 'someValue';

默认情况下,这将在您的所有应用程序中定义一个变量,但您可以通过在specific recognized folderclientserver文件夹中)编写该声明来限制它。

然而,这个变量绝对不会首先被定义。它将在Meteor运行定义它的实际代码时定义。因此,它可能不是最佳做法,因为您将不得不努力解决加载顺序,并且它会使您的代码依赖于Meteor loads files:您将文件放入哪个文件夹,文件名称...如果您略微触摸您的架构,您的代码很容易出现混乱错误。

正如我在another closely related post中建议的那样,你应该直接去找一个包裹!

答案 1 :(得分:11)

使用var关键字声明的Meteor中的变量的范围限定在它们声明的文件中。

如果要创建全局变量,请执行此操作

Schemas = {}

答案 2 :(得分:3)

ReferenceError是Node错误。 Meteor是Node之上的框架。

Node具有全局范围(又名Node' s global变量)。 如果您尝试访问未定义的全局变量,则Node(而不是Meteor)会抛出此错误。

浏览器还有一个名为window的全局范围,并且在访问未定义的变量时不会抛出ReferenceErrors。

这是我喜欢为类添加功能的模式(它是非常流星):

/lib/Helpers.js      <-- Helpers for everyone (node+browser)
/server/Helpers.js   <-- Server helpers (node)
/client/Helpers.js   <-- Client helpers (browser)

考虑以下实施:

// /lib/Helpers.js
Helpers = {/* functions */};  // Assigned to window.Helpers and global.Helpers

// /server/Helpers.js
Helpers = _.extend(Helpers, {/*more functions*/}

// /client/Helpers.js
Helpers = _.extend(Helpers, {/*more functions*/}

这是一个微不足道的例子。如果我不想担心加载顺序怎么办?为什么不在/lib/Helpers.js中使用_.extend()?

// /lib/Helpers.js
// Helpers = {/* functions */};                  // Overwrites...
Helpers = _.extend(Helpers, {/* functions */});  // ReferenceError

因为如果未定义助手,您将从Node获得ReferenceError - 特别是&#34; Helpers&#34;用作参数。 (Node知道将Helpers指定为global.Helpers)。

以下两种方法可以解决&#34;这样:

1)将助手分配给某事

// /lib/Helpers.js
// Helpers = Helpers || {}    // would be another ReferenceError
if (typeof Helpers === 'undefined') Helpers = {};
Helpers = _.extend(Helpers, {/* functions */});

2)使用全球

中的助手
// /lib/Helpers.js
Helpers = _.extend(global.Helpers, {/* functions */});  // works in node, but...

两者都很糟糕。

1)语法很糟糕   2)在节点中工作,但浏览器中没有全局。所以它没有达到它的目的。

所以我放弃了,并在lib中第一次重写它,并在任何被覆盖的情况下寻找运行时错误。

如果你有一个方便的跨浏览器语法,请做评论:-)     var something = something || {}     something.blah = foo;

此处还有其他JS shorthand tips

答案 3 :(得分:1)

会话变量是全局的,可以轻松地在不同的文件/函数中访问。 Session.setPersistent用于在所有文件中持久设置变量名称。当他们的应用程序太大而没有被删除时(因此可能存在内存泄漏)并且可能在控制台中给出错误(如果未定义等),可能会限制使用会话变量。链接到文档:https://docs.meteor.com/api/session.html